How to use value element in xpath for selenium-java? - xpath

I used this xpath locator:
//table/following::div[text()='value']/preceding::span[#class='x-grid-checkcolumn'][1]"}
on the page i scripted as:
public void selectTestPlan(String value) {
String[] path = {ChatTestingPagePath2.ChatTestManagement.TEST_PLAN_CHECKBOX[0].replace("{value}", value),ChatTestingPagePath2.ChatTestManagement.TEST_PLAN_CHECKBOX[1]};
click(path);
}
but it always failed, it says that it was unable to locate the element.
Hoping for your response.
Thank you!
However when changing the value in specific value like this:
//table/following::div[text()='Testing']/preceding::span[#class='x-grid-checkcolumn'][1]"}
and use the page as:
public void selectTestPlan() {
String[] path = {ChatTestingPagePath2.ChatTestManagement.TEST_PLAN_CHECKBOX[0], value),ChatTestingPagePath2.ChatTestManagement.TEST_PLAN_CHECKBOX[1]};
click(path);
}
it will passed the automated test.

This should work:
public void selectTestPlan(String value) {
String path = "//table/following::div[text()='%s'] preceding::span[#class='x-grid-checkcolumn'][1]";
click(String.format(path, value));
}
I hope it helps!

Related

Call several different JavaScript within AjaxLink one after the other

When I click on an AjaxLink, I would like to have a validation via JavaScript on the client side first (because the LocalStorage is queried) and then depending on the result, further JavaScript calls are made. How can i achieve this?
In a pseudo code it would look like this:
new AjaxLink<>("myId", myModel) {
#Override
public void onClick(AjaxRequestTarget target) {
boolean isCounterValid = target.appendJavaScript(checkCounter()); // i know that this is not possible, therefore pseudo code
if(isCounterValid) {
target.appendJavaScript(someOtherJavaScript());
}
else {
target.appendJavaScript(anotherJavaScript());
}
}
private String checkCounter() {
return "var count = window.localStorage.getItem('myCounter'); return count !== 1;";
}
private String someOtherJavaScript() {
return "change something";
}
private String anotherJavaScript() {
return "change other thing";
}
};
You need to send extra request parameters with the Ajax call when the link is clicked. For that you should override updateAjaxAttributes(AjaxRequestAttributes attributes) method of AjaxLink:
#Override
protected void updateAjaxAttributes(AjaxRequestAttributes attributes)
{
attributes.getDynamicExtraParameters().add("var count = window.localStorage.getItem('myCounter'); return [{\"name\":\"count\", \"value\": count}]");
}
This way inside AjaxLink#onClick() you can read the count via:
int count = getRequest().getRequestParameters().getParameterValue("count").toInt();
AJAX components and behaviors can customize AJAX attributes overriding updateAjaxAttributes and using a custom implementation of AjaxCallListener which exposes different method to hook into the AJAX request cycle. In you case you could use AjaxCallListener#getBeforeSendHandler.
For a full introduction to this topic (with examples) see user guide:
https://ci.apache.org/projects/wicket/guide/8.x/single.html#_ajax_request_attributes_and_call_listeners

XPathDocument Error Will not write to file c#

private void SetValueToDocumentByXPath(XPathDocument doc, string xpath, string value)
{
var nav = doc.CreateNavigator();
var it = nav.Select(xpath, nameSpaceManager_);
if (it.MoveNext())
{
it.Current.SetValue(value);
}
}
Since I have changed the document coming in as a parameter I am getting this error:
Additional information: Specified method is not supported.
I would like to Edit the doc coming into the function

How to validate web api response

I am working on a web api where I need to validate response returned. I want to write some generic code to ensure that response returned from api is in a correct format.
Basically there are fields like status, remarks etc which should be present in response if these are null or invalid then i should return some error code but not sure how to achieve this, can someone guide me here? Thanks in advance.
Thanks,
Sudama
The following might work for you. It assumes you're using an ObjectResult though you can adapt it to the IActionResult implementation that you're actually using. The following is not production code; rather, it gives a sense of what you could do.
public class MyResultFilter : IResultFilter
{
public void OnResultExecuted(ResultExecutedContext context)
{
}
public void OnResultExecuting(ResultExecutingContext context)
{
var result = context.Result as ObjectResult;
var value = result.Value as MyCustomType;
if (!IsValid(value)
{
context.Result = new StatusCodeResult(500);
}
}
private bool IsValid(MyCustomType value)
{
return value != null &&
value.Status != null &&
value.Remarks != null;
}
}

How to use MethodCallExpression.Update

I'm trying and failing to use an ExpressionVisitor to modify an expression that calls a method. I have a SearchService that encapsulates the search logic and want to be able to amend the search arguments passed.
The class in which the SearchFunc should be modified and run:
public class SearchService
{
public Expression<Func<string, string, List<int>>> SearchFunc { get; set; }
public void Run()
{
SearchModifier modifier = new SearchModifier();
Expression<Func<string, string, List<int>>> newFunc = (Expression<Func<string, string, List<int>>>)modifier.Modify(SearchFunc);
}
}
SearchModifier is defined as:
public class SearchModifier : ExpressionVisitor
{
public Expression Modify(Expression expression)
{
return Visit(expression);
}
protected override Expression VisitMethodCall(MethodCallExpression node)
{
Debug.Print(string.Format("VisitMethodCall: {0}", node.ToString()));
//VisitMethodCall: value(ExpressionTree_test.MainWindow)._adminRepository.SearchUsers("orig val", "orig val2")
//trying to use the Update method to create an amended MethodCallExpression
List<ConstantExpression> newargs = new List<ConstantExpression>();
newargs.Add(Expression.Constant("my new arg 1", typeof(string)));
newargs.Add(Expression.Constant("my new arg 2", typeof(string)));
MethodCallExpression methodCallExpression = node.Update(node, newargs);
//causes exception
//Method 'System.Collections.Generic.List`1[System.Int32] SearchUsers(System.String, System.String)' declared
//on type 'ExpressionTree_test.AdminRepository' cannot be called
//with instance of type 'System.Collections.Generic.List`1[System.Int32]'
Debug.Print(string.Format("Amended VisitMethodCall: {0}", methodCallExpression.ToString()));
return base.VisitMethodCall(node);
}
The Run method is called like this:
_searchService = new SearchService();
_searchService.SearchFunc = (t, s) => _adminRepository.SearchUsers("orig val", "orig val2");
I can't find much information on using the MethodCallExpression.Update method so am not sure I'm doing this correctly. How to I change the values of the arguments in the method?
Of course there may be a better way of doing this and any suggestions gratefully received...
You're not using the result of the Update method. You should pass it to base.VisitMethodCall instead of node:
return base.VisitMethodCall(methodCallExpression);
EDIT
Sorry, I misread the question... The first argument to Update is not the expression node being visited, it's the instance on which the method is called. So the code should be:
node.Update(node.Object, newargs);

Waiting for a text change in WatiN

I am trying to test a web page that has ajax calls to update a price.
An ajax call is fired on page load to update an initially empty div.
This is the extension method I'm using to wait for a change in the inner text of the div.
public static void WaitForTextChange(this IE ie, string id)
{
string old = ie.Element(id).Text;
ie.Element(id).WaitUntil(!Find.ByText(old));
}
However it's not pausing even though when I write out the old value and ie.Element(id).Text after the wait, they are both null. I can't debug as this acts as a pause.
Can the Find.ByText not handle nulls or have I got something wrong.
Has anyone got some code working similar to this?
I found my own solution in the end after delving into WatiN's constraints.
Here's the solution:
public class TextConstraint : Constraint
{
private readonly string _text;
private readonly bool _negate;
public TextConstraint(string text)
{
_text = text;
_negate = false;
}
public TextConstraint(string text, bool negate)
{
_text = text;
_negate = negate;
}
public override void WriteDescriptionTo(TextWriter writer)
{
writer.Write("Find text to{0} match {1}.", _negate ? " not" : "", _text);
}
protected override bool MatchesImpl(IAttributeBag attributeBag, ConstraintContext context)
{
return (attributeBag.GetAdapter<Element>().Text == _text) ^ _negate;
}
}
And the updated extension method:
public static void WaitForTextChange(this IE ie, Element element)
{
string old = element.Text;
element.WaitUntil(new TextConstraint(old, true));
}
It assumes that the old value will be read before the change so there's a slight chance of a race condition if you use it too long after setting off the update but it works for me.

Resources