Java.Selenium. How to put not constant variable inside of xpath? - java

I am working with Java Selenium. And I need to put String line computeEngine.getMachineSeries() from properties inside of my xpath. How can I do this?
#FindBys({#FindBy(xpath = "//md-option//div[#class='md-text ng-binding'][contains(text(), '"+computeEngine.getMachineSeries()+"')]")})
List<WebElement> seriesOptionNOne;
I cant use this code above, because of this error: "Attribute value must be constant". How can I do this in another way?

You can try the following solution:
String myString = computeEngine.getMachineSeries();
#FindBys({#FindBy(xpath = "//md-option//div[#class='md-text ng-binding'][contains(., '"+ myString +"')]")})
List<WebElement> seriesOptionNOne;

Not possible:
https://stackoverflow.com/a/10636320/1387701
There is no way to dynamically generate a string used in an
annotation. The compiler evaluates annotation metadata for
RetentionPolicy.RUNTIME annotations at compile time, but
GENERIC_GENERATED_NAME isn't known until runtime. And you can't use
generated values for annotations that are RetentionPolicy.SOURCE
because they are discarded after compile time, so those generated
values would never be known.

Related

Appium NOT locating element when java variable is used in xpath

I'm trying to locate elements dynamically usign the xpath. However, when I use variable in the xpath, elements are NOT located. However, if I use hardcoded value, elements are located properly.
What am I missing here?
Below xpath locates the elements perfectly:
driver.findElements(By.xpath("//XCUIElementTypeStaticText[contains(#value, 'hp')]"));
whereas, below xpath doesn't locate the elements:
driver.findElements(By.xpath("//XCUIElementTypeStaticText[contains(#value, '" + device + "')]"));
Please note that , there are multiple elements matching the above xpath.
I even tried below code but of no use:
driver.findElements(By.XPath(String.Format("//XCUIElementTypeStaticText[contains(#value, '{0}')]", device)));
Any help would be appreciated.
Try do debug this issue as following:
Define the XPath string before calling driver.findElements method, format the string to have the proper value and then pass it into Selenium method, as following:
String xpathLocator = "//XCUIElementTypeStaticText[contains(#value, '%s')]";
xpathLocator = String.format(xpathLocator, device);
driver.findElements(By.xpath(xpathLocator));
As about your existing code.
Here driver.findElements(By.xpath("//XCUIElementTypeStaticText[contains(#value, '" + device + "')]"));
I can't see the formatting action.
And here driver.FindElements(By.XPath(string.Format("//XCUIElementTypeStaticText[contains(#value, '{0}')]", device)));
it seems to be a wrong syntax.
It should be String.format while you wrote string.Format
Try trimming the spaces as:
driver.findElements(By.xpath("//XCUIElementTypeStaticText[contains(#value, '"+device+"')]"));
Or using String.format() as:
String device = "hp";
driver.findElements(By.xpath(String.format("//XCUIElementTypeStaticText[contains(#value, '%s')]", device)));
Note:
Instead of FindElements() it should be findElements()
Instead of String.Format() it should be String.format()
The issue was with the case mismatch in the value returned by variable. i.e; device variable was returning 'hP' instead of 'hp'.
Corrected the code and it works fine now.

Update attribute value using vtd-xml

Given an xpath to an attribute and a new value, I am looking to update the attribute value to the new value.
I have followed the example here: http://vtd-xml.sourceforge.net/codeSample/cs7.html and come up with the following:
autoPilot.selectXPath(xpath);
modifier.updateToken(vtdNav.getAttrVal(vtdNav.toString(autoPilot.evalXPath())), newContent);
...my tests all pass but perhaps because I am not used to the "tokenized" way that vtd-xml works, it doesn't "feel" right so I am just looking for affirmation that I've done the correct thing.
Your code will work just fine... assume you will call modifier.output().
but it is not optimal...
This statement
modifier.updateToken(vtdNav.getAttrVal(vtdNav.toString(autoPilot.evalXPath())), newContent);
Can be written as
modifier.updateToken(autoPilot.evalXPath()+1, newContent);
Because if the attribute name has an index value of i (!=-1), then the attrinute value is always i+1... as attr val immediately follows an attr name. No conditional check is needed.

How to replace a query string in an Apache Velocity template?

In my web application I'm trying to prevent users from inserting JavaScript in the freeText parameter when they're running a search.
To do this, I've written code in the header Velocity file to check whether the query string contains a parameter called freeText, and if so, use the replace method to replace the characters within the parameter value. However, when you load the page, it still displays the original query string - I'm unsure on how to replace the original query string with my new one which has the replaced characters.
This is my code:
#set($freeTextParameter = "$request.getParameter('freeText')")
freeTextParameter: $freeTextParameter
#if($freeTextParameter)
##Do the replacement:
#set($replacedQueryString = "$freeTextParameter.replace('confirm','replaced')")
replacedQueryString after doing the replace: $replacedQueryString
The query string now: $request.getQueryString()
The freeText parameter now: $request.getParameter('freeText')
#end
In the code above, the replacedQueryString variable has changed as expected (ie the replacement has been carried out as expected), but the $request.getQueryString() and $request.getParameter('freeText') are still the same as before, as if the replacement had never happened.
Seeing as there is a request.getParameter method which works fine for getting the parameters, I assumed there would be a request.setParameter method to do the same thing in reverse, but there isn't.
The Java String is an immutable object, which means that the replace() method will return an altered string, without changing the original one.
Since the parameters map given by the HttpServletRequest object cannot be modified, this approach doesn't work well if your templates rely on $request.getParameter('freeText').
Instead, if you rely on VelocityTools, then you can rather rely on $params.freeText in your templates. Then, you can tune your WEB-INF/tools.xml file to make this parameters map alterable:
<?xml version="1.0">
<tools>
<toolbox scope="request">
<tool key="params" readOnly="false"/>
...
</toolbox>
...
</tools>
(Version 2.0+ of the tools is required).
Then, in your header, you can do:
#set($params.freeText = params.freeText.replace('confirm','replaced'))
I managed to fix the issue myself - it turned out that there was another file (which gets called on every page) in which the $!request.getParameter('freeText')" variable is used. I have updated that file so that it uses the new $!replacedQueryString variable (ie the one with the JavaScript stripped out) instead of the existing "$!request.getParameter('freeText')" variable. This now prevents the JavaScript from being executed on every page.
So, this is the final working code in the header Velocity file:
#set($freeTextParameter = "$!m.request.httpRequest.getParameter('freeText')")
#if($freeTextParameter)
#set($replacedQueryString = "$freeTextParameter.replace('confirm','').replace('<','').replace('>','').replace('(','').replace(')','').replace(';','').replace('/','').replace('\"','').replace('&','').replace('+','').replace('script','').replace('prompt','').replace('*','').replace('.','')")
#end

HTML Java parsing basic error?

Should be a relatively easy question, but as I am a newbie to java, I dont know the answer!
I have the following code:
String FTSE = "http://www.bloomberg.com/quote/UKX:IND/members";
doc = Jsoup.connect(FTSE).get();
Elements trs = doc.select("tr:has(a[href='/quote/III:LN'])");
Elements values = trs.select("td.value");
link = values.get(0);
System.out.println("text : " + link.text());
However, there are red squiggly lines in eclipse under the word 'link' in the penultimate and final line, and when I hover over it, it says this- link cannot be resolved to a variable.
How do I fix this?
Cheers
You are trying to assign values.get(0) to a variable link, which, as Eclipse thinks, was not defined or defined elsewhere. There are two problems and two possible solutions:
You never defined link. Define it and assign it the type of what values.get returns:
SomeType link = values.get(0);
You defined link in another method. Since it's not in the same scope, you must define it for the global scope and then use it with this keyword:
this.link = values.get(0);
It seems that link is not defined. Try:
YourClass link = (YourClass)values.get(0);
Instead of YourClass use the class that values.get returns.

How do I get JavaScript Values from Selenium?

I am running the following code (Java selenium client)- PAGE_NUMBER has a value, but I am unable to get it using selenium:
String script = "var cellValue = selenium.browserbot.getUserWindow().PAGE_NUMBER;";
selenium.runScript(script);
String value = selenium.getEval("selenium.browserbot.getUserWindow().cellValue;");
System.out.println("Value: " + value);
I don't know Selenium 1 at all and Selenium2/Webdriver is very different. However there are three things that I suspect to play a role in this issue:
Scope: You declared the variable as local to the scope of the script (by writing var). You might try using a global variable by omitting the var keyword, so that you can access it later.
Why do you try to access the variable via selenium.browserbot.getUserWindow().. Try omitting this part.
The semicolon after cellValue is probably no good idea either
And then again, why not simply using
String value = selenium.getEval("selenium.browserbot.getUserWindow().PAGE_NUMBER");
?
I hope at least some part of this answer helps you. As I said I am just guessing.

Categories

Resources