My Companys website is compatible only with IE. So i cannot use IDE for recording webdriver scripts.
There are HTML pages which has about 100 or 200(not exact count) of textboxes and Dropdowns.
Writing java code to automate this is very much tedious.
Can someone provide me with tool or utility to read the HTML file itself and generate the corresponding code ?
Or guide me how to develop a utility to meet my need ?
For example :
Consider an html file like this
<html>
<body>
<input name = "employee_name" />
<select id = "designation">
<option value = "MD">MD</option>
<option value = "programmer"> Programmer </option>
<option value = "CEO"> CEO </option>
</option>
<body>
</html>
If i give this file as input to utility it will generate me a java file like this
WebDriver driver = new InternetExplorerDriver();
WebElement employee_name = driver.findElement(By.name("employee_name"));
employee_name.sendKeys("...");
Select designation = new Select(driver.findElement(By.id("designation")));
designation.selectByVisibleText("...");
Thanks in Advance !
You should be using "Selenium Builder" rather than "Selenium IDE", BUT, in theory, you could get all similar elements from a page in a group like so:
List<WebElement> bodyinputs = driver
.findElements( By.xpath("//div[#class='body']/input") );
List<WebElement> footeranchors = driver
.findElements( By.xpath("//div[#class='footer']/a") );
Then, for each of these groups, you can loop through the lists and use a JavaScriptExecutor to evaluate and figure out the XPath for each element and store the XPath in a hashtable with each Element:
protected String getXPath() {
String jscript = "function getPathTo(node) {" +
" var stack = [];" +
" while(node.parentNode !== null) {" +
" stack.unshift(node.tagName);" +
" node = node.parentNode;" +
" }" +
" return stack.join('/');" +
"}" +
"return getPathTo(arguments[0]);";
return (String) driver.executeScript(jscript, webElement);
}
Then, the final step, you can auto-generate "By locators" using the HashTable as input.
But even if you do that you still need to write code to intelligently figure out which By locators get which inputs and which ones don't.
Related
I need to get text value as indicated below:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<b>Some Text I can find using xPath</b>
<hr>
**TEXT I WOULD LIKE TO FIND THAT IS BEING ADDED DYNAMICALLY - it will be different number every time page loads**
<hr>
**some other text dynamically added**
</body>
</html>
I tried by using
driver.findElement(By.xpath("/html/body/text()[1]"));
with no luck.
It's not straight forward due to the WebDriver not handling anything but element nodes. I opened a while ago two issues: one against the WebDriver and another one against the W3C WebDriver specification. (vote for them if, it helps showing a need of the user base).
Meanwhile, as a (painful) workaround, you will need to rely on JavascriptExecutor capabilities of your WebDriver. An example (in another context, thus will have to be adapted to your specifics), in one of my older answers.
Adapted to your case, with the note it may contain bugs cause by typos (I haven't checked it):
WebElement contextNode=driver.findElement(By.xpath("/html/body"));
if(driver instanceof JavascriptExecutor) {
String jswalker=
"var tw = document.createTreeWalker("
+ "arguments[0],"
+ "NodeFilter.SHOW_TEXT,"
+ "{ acceptNode: function(node) { return NodeFilter.FILTER_ACCEPT;} },"
+ "false"
+ ");"
+ "var ret=null;"
// skip over the number of text nodes indicated by the arguments[1]
+ "var skip;"
+ "for(skip=0; tw.nextNode() && skip<arguments[1]; skip++);"
+ "if(skip==arguments[1]) { " // found before tw.nextNode() ran out
+ "ret=tw.currentNode.wholeText.trim();"
+ "}"
+ "return ret;"
;
int textNodeIndex=3; // there will be empty text nodes before after <b>
Object val=((JavascriptExecutor) driver).executeScript(
jswalker, contextNode, textNodeIndex
);
String textThatINeed=(null!=val ? val.toString() : null);
}
Please let me know if/how it works.
I am having difficulty selecting options from a dropdown list using Selenium Webdriver. Below is the HTML snippet:
<span id="id14">
<div class="stadium-input-row">
<span class="inputContainer">
<select id="id1f" class="departurePoint stadiumSelect" onchange="var wcall=..........">
<option value="">Please select</option>
<option value="BHX"> Birmingham - (BHX) </option>
<option value="GLA"> Glasgow - (GLA) </option>
<option value="LON"> London - (LON) </option>
<option value="MAN"> Manchester - (MAN) </option>............
The select tag id changes each time the DOM is loaded.
The select tag is greyed out until it is interacted with.
My code
Select oSelect = new Select(driver.findElement(By.xpath("(.//select)[1]"));
oSelect.selectByVisibleText("Birmingham");
Error
org.openqa.selenium.NoSuchElementException: Cannot locate element
with text: Birmingham
In debugging mode, the dropdown does not seem to be activated (clicked) by the driver.
There's a weird (at least it's weird to me) thing going on on that site. The SELECT that you are trying to access is permanently hidden (which means it can't be interacted with using Selenium). Users interact with DIVs, etc. via a fake dropdown (it's not a SELECT) and the result of those selections are stored in the hidden SELECT. There are two ways to accomplish your task.
Deal with what you can see.
This is really a pain on this site. I think it can be ultimately done but I don't want to spend any more time on it myself so I'll show you the door and you'll have to pick up where I left off. The code below will open the departure dropdown. From there, you find the departure airport and click on it. Done. Harder than it sounds...
driver.findElement(By.cssSelector("div.custom-select.departurePoint.airportSelect")).click();
Cheat and use JavascriptExecutor.
NOTE: By doing this you are no longer executing a real user scenario since users can't click on hidden elements or inject Javascript commands into the page. As long as you are OK with this, here's a sample.
This code executes Javascript on the page using the JavascriptExecutor. You pass the function a string you are looking for in the options, e.g. you can pass "EMA" or "East Midlands - (EMA)" or anywhere inbetween. The JS code will grab the hidden SELECT, search through the OPTIONS, and select the first that matches.
Also note: You will not see the UI update with the selection. Once you click SEARCH, it will work. I have tried it myself and it works.
Yet another note: I use Eclipse as my editor so the // #formatter:off you see in the code below keeps Eclipse from wrapping/reformatting the extra long string that contains the JS code. You can leave or remove it as you like. I like it there because I can still read the JS code with it formatted and indented like it is and I don't want Eclipse messing it up.
selectOption("EMA");
public void selectOption(String option)
{
// #formatter:off
String script =
"function selectOption(s) {\r\n" +
" var sel = document.querySelector('select.departurePoint.airportSelect');\r\n" +
" for (var i = 0; i < sel.options.length; i++)\r\n" +
" {\r\n" +
" if (sel.options[i].text.indexOf(s) > -1)\r\n" +
" {\r\n" +
" sel.options[i].selected = true;\r\n" +
" break;\r\n" +
" }\r\n" +
" }\r\n" +
"}\r\n" +
"return selectOption('" + option + "');";
// #formatter:on
((JavascriptExecutor) driver).executeScript(script);
}
what you need to do:
List<WebElement> options = driver.findElement(By.xpath("//div[#class='stadium-input-row']//select")).findElements(By.tagName("option"));
that will create you list of option tags as WebElement objects
or
Select oSelect = new Select(driver.findElement(By.xpath("//div[#class='stadium-input-row']//select"));
or just take the select as WebElement object
WebElement selectElement = driver.findElement(By.xpath("//div[#class='stadium-input-row']//select"));
Hovering element
Actions action = new Actions(driver);
WebElement hoverElement = driver.findElement(By.xpath("//div[#class='stadium-input-row']//select"));
action.moveToElement(hoverElement);
action.click().build().perform();
As your exception clearly says Cannot locate element with text: Birmingham means it compares with whole visible text option so you should try as below :-
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement select = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("(.//select)[1]")));
Select oSelect = new Select(select);
oSelect.selectByVisibleText("Birmingham - (BHX)");
or
oSelect.selectByIndex(1);
or
oSelect.selectByValue("BHX");
Edited :- If unfortunately none of the above solution works you should try using JavascriptExecutor as below :-
((JavascriptExecutor)driver).executeScript("var select = arguments[0]; for(var i = 0; i < select.options.length; i++){ if(select.options[i].text.indexOf(arguments[1]) != -1){ select.options[i].selected = true; } }",
driver.findElement(By.xpath("(.//select)[1]")),
"Birmingham");
Hope it will help you..:)
Select will not work in all the situations. Try this code
List <WebElement> options = driver.findElements(By.xpath("Target Element with Options"));
String element;
for(int i=0;i<options.size();i++)
{
element = options[i].get(i).getAttribute("value");
if(element.equals("BHX")){
options.get(i).click();
}
}
In below mentioned HTML code wana pick " page = ? " value from particular "href" tag . so i can pick that value and use that particular value in my selenium webdriver script , so my loop will run till 53 page.
this " page = " value mention in "href" tag please tell me how to pick page = value
<li>
<a id="quotes_content_left_lb_LastPage" class="pagerlink" href="http://www.abcd.com/symbol/ctsh/institutional-holdings?page=53">last >></a>
</li>
var arr = document.getElementById('quotes_content_left_lb_LastPage').href.split('=');
var value = arr[arr.length-1];
//value equals 53
Is this what you need?
Try with:
WebElement lnk = driver.findElement(By.id("quotes_content_left_lb_LastPage"));
int loopCount = Integer.parseInt(lnk.getAttribute("href").split("page=")[1]);
Basically you can use getAttribute function of WebElement interface to get value of any attribute and after that, its pure java.
I'm currently trying to scrape amazon for a bunch of data. I'm using jsoup to help me do this, and everything has gone pretty smoothly, but for some reason I can't figure out how to pull the current number of sellers selling new products.
Here's an example of the url I'm scraping : http://www.amazon.com/dp/B006L7KIWG
I want to extract "39 new" from the following below:
<div id="secondaryUsedAndNew" class="mbcOlp">
<div class="mbcOlpLink">
<a class="buyAction" href="/gp/offer-listing/B006L7KIWG/ref=dp_olp_new_mbc?ie=UTF8&condition=new">
39 new
</a> from
<span class="price">$60.00</span>
</div>
</div>
This project is the first time I've used jsoup, so the coding may be a bit iffy, but here are some of the things I have tried:
String asinPage = "http://www.amazon.com/dp/" + getAsin();
try {
Document document = Jsoup.connect(asinPage).timeout(timeout).get();
.....
//get new sellers try one
Elements links = document.select("a[href]");
for (Element link : links) {
// System.out.println("Span olp:"+link.text());
String code = link.attr("abs:href");
String label = trim(link.text(), 35);
if (label.contains("new")) {
System.out.println(label + " : " + code);
}
}
//get new sellers try one
Elements links = document.select("div.mbcOlpLink");
for (Element link : links) {
// System.out.println("Span olp:"+link.text());
}
//about a million other failed attempts that you'll just have to take my word on.
I've been successful when scrape everything else I need on the page, but for some reason this particular element is being a pain, any help would be GREAT! Thanks guys!
I would use
String s = document.select("div[id=secondaryUsedAndNew] a.buyAction").text.replace(" "," ");
This should leave you "42 new" as it says on the page at this moment.
Hope this works for you!
I'm trying to use Selenium WebDriver to input text to a GWT input element that has default text, "Enter User ID". Here are a few ways I've tried to get this to work:
searchField.click();
if(!searchField.getAttribute("value").isEmpty()) {
// clear field, if not already empty
searchField.clear();
}
if(!searchField.getAttribute("value").isEmpty()) {
// if it still didn't clear, click away and click back
externalLinksHeader.click();
searchField.click();
}
searchField.sendKeys(username);
The strange thing is the above this only works some of the time. Sometimes, it ends up searching for "Enter User IDus", basically beginning to type "username" after the default text -- and not even finishing that.
Any other better, more reliable ways to clear out default text from a GWT element?
Edited to add: The HTML of the input element. Unfortunately, there's not much to see, thanks to the JS/GWT hotness. Here's the field when it's unselected:
<input type="text" class="gwt-TextBox empty" maxlength="40">
After I've clicked it and given it focus manually, the default text and the "empty" class are removed.
The JS to setDefaultText() gets called both onBlur() and onChange() if the change results in an empty text field. Guess that's why the searchField.clear() isn't helping.
I've also stepped through this method in debug mode, and in that case, it never works. When run normally, it works the majority of the time. I can't say why, though.
Okay, the script obviously kicks in when the clear() method clears the input and leaves it empty. The solutions it came up with are given below.
The naïve one, presses Backspace 10 times:
String b = Keys.BACK_SPACE.toString();
searchField.sendKeys(b+b+b+b+b+b+b+b+b+b + username);
(StringUtils.repeat() from Apache Commons Lang or Google Guava's Strings.repeat() may come in handy)
The nicer one using Ctrl+A, Delete:
String del = Keys.chord(Keys.CONTROL, "a") + Keys.DELETE;
searchField.sendKeys(del + username);
Deleting the content of the input via JavaScript:
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("arguments[0].value = '';", searchField);
searchField.sendKeys(username);
Setting the value of the input via JavaScript altogether:
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("arguments[0].value = '" + username + "';", searchField);
Note that javascript might not always work, as shown here: Why can't I clear an input field with javascript?
For what it is worth I'm have a very similar issue. WebDriver 2.28.0 and FireFox 18.0.1
I'm also using GWT but can reproduce it with simple HTML/JS:
<html>
<body>
<div>
<h3>Box one</h3>
<input id="boxOne" type="text" onfocus="if (this.value == 'foo') this.value = '';" onblur="if (this.value == '') this.value = 'foo';"/>
</div>
<div>
<h3>Box two</h3>
<input id="boxTwo" type="text" />
</div>
</body>
</html>
This test fails most of the time:
#Test
public void testTextFocusBlurDirect() throws Exception {
FirefoxDriver driver = new FirefoxDriver();
driver.navigate().to(getClass().getResource("/TestTextFocusBlur.html"));
for (int i = 0; i < 200; i++) {
String magic = "test" + System.currentTimeMillis();
driver.findElementById("boxOne").clear();
Thread.sleep(100);
driver.findElementById("boxOne").sendKeys(magic);
Thread.sleep(100);
driver.findElementById("boxTwo").clear();
Thread.sleep(100);
driver.findElementById("boxTwo").sendKeys("" + i);
Thread.sleep(100);
assertEquals(magic, driver.findElementById("boxOne").getAttribute("value"));
}
driver.quit();
}
It could just be the OS taking focus away from the browser in a way WebDriver can't control. We don't seem to get this issue on the CI server to maybe that is the case.
I cannot add a comment yet, so I am putting it as an answer here. I want to inform you that if you want to use only javascript to clear and/or edit an input text field, then the javascript approach given by #slanec will not work. Here is an example: Why can't I clear an input field with javascript?
In case you use c# then solution would be :
// provide some text
webElement.SendKeys("aa");
// this is how you use this in C# , VS
String b = Keys.Backspace.ToString();
// then provide back space few times
webElement.SendKeys(b + b + b + b + b + b + b + b + b + b);