I am facing problem with selenium webdriver to locate an element by xpath. I am not a web developer or tester. Something came up in my day to day task and need to connect to a website via script as part of automation.So can some one help me with this.
Given below xml, I would like autofill Username and Password.
<div class="fd-form-group">
<div class="fd-form-item">
<label class="fd-form-label">Username</label>
<input autocomplete="username" class="fd-input" type="text">
</div>
</div>
<div class="fd-form-group">
<div class="fd-form-item">
<label class="fd-form-label">Password</label>
<input autocomplete="current-password" class="fd-input" type="password">
</div>
</div>
As a first step I tried to locate these elements with below code
System.setProperty("webdriver.gecko.driver", "/some/path/geckodriver")
val driver = new FirefoxDriver()
val myWait = new WebDriverWait(driver, 30)
val myWebsite = "https://my/website"
try {
driver.get(myWebsite)
// locate username
myWait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//input[#type='text']")))
} finally driver.quit
I get this error :Exception in thread "main" org.openqa.selenium.TimeoutException: Expected condition failed: waiting for presence of element located by: By.xpath: //input[#type='text']
I also tried with #class, but didnt help me.I am aware that this question is asked by many other users and solved with various method. But none of those helping me here as I dont know much about these things. So I really appreciate if some one helps
You need to target input fields not label.
UserName xpath :
//label[text()='Username']/following-sibling::input
Password xpath :
//label[text()='Password']/following-sibling::input
and use it like below :
myWait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//label[text()='Username']/following-sibling::input"))).sendKeys("Your username")
I am not sure why you are using driver.switchTo().defaultContent() Is it in iframe ? or in a new window ?
Accordingly to the details in your question I guess there is an iframe there so you have to switch into the iframe first and then try accessing those elements. Like this:
driver.switchTo().frame(driver.findElement(By.id("frameId")));
myWait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//input[#type='text']")))
and finally, when you finished with that iframe go back to the default content
driver.switchTo().defaultContent()
Related
How to handle this kind of pop-up. My goal is to get the message when Submit button clicked then validate it againts my own text (maybe using assert). I've tried to locate the element using firepath (xpath) but when i click locate Element button on firebug, the pop-up disappear.
Here is the screenshot of the pop-up.
popUp
Here is the code :
<p class="errors"></p>
<input id="email" class="form-control" type="email" value="" name="email" required="" oninput="setCustomValidity('')" oninvalid="this.setCustomValidity('Email Cannot Be Empty')" placeholder="Email *" data-placeholder="X" data-format="">
Thank you in advance.
From the scrrenshot it looks like a tooltip. Something like when we mouse over Google title in https://www.google.co.in/.
To verify tooltip we can get the attribute 'title' and verify.
Example : in https://www.google.co.in/. tooltip is placed in title attribute as below.
title="Google"
<div id="hplogo" style="background-size:272px 92px;height:92px;width:272px" title="Google" onload="window.lol&&lol()" align="left">
For your scenario, the displayed tip message is available in 'oninvalid' attribute as below. So get this attribute value and validate it.
oninvalid="this.setCustomValidity('Email Cannot Be Empty')"
If the element is not inside a iframe, then you can directly try as follows:
String emailId = driver.findElement(By.id("email")).getText()
// write string equals login here comparing emailId that is captured and the one you want to compare to.
if not, first find the iframeand switch to it and then use above code to find the element. More detailed answer related to switching b/w frame is here
Finding the elements in the Pop-up:
Instead of clicking on the Locate Element button (of Firebug) first, Right click on the element you want to find in the Pop-up, and select Inspect with Firebug, which gives the corresponding HTML code for the element.
This is a bit late in the game but the way you get the custom validity message and not the generic one you have to call the reportValidity() event within JavaScript in Selenium. You'll see a driver.executeScript() method and this is where you must call the reportValidity event on the element being validated. This is how I did it:
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions
.ElementToBeClickable(By.CssSelector("input#NewPassword.form-control")));
IWebElement input = driver.FindElement(By.CssSelector("input#NewPassword.form-control"));
input.SendKeys(string.Empty);
IWebElement form = driver.FindElement(By.TagName("form"));
form.Submit();
driver.ExecuteScript("document.getElementById('NewPassword').reportValidity();");
Assert.AreEqual("New password required", input.GetAttribute("validationMessage"));
For the text type WebElement that I am trying to click and do a send keys using WebDriver, I am getting an "Element is not currently visible and so may not be interacted with". I went through similar posts here in stackoverflow but the solutions posted there did not work for me.
I tried the javascript method as below without any success as I got nullpointer exception
WebElement el = driver.findElement(map.getLocator("timesheet.intime"));
js.executeScript("arguments[0].checked=true;", el);
I use the object repository method to get the locator.
//timesheet.intime=xpath://input[contains(#id,'txtSignIn')]
The HTML
<input id="gvTimesheetDay1_ctl02_txtSignIn" class="form-control input-sm" type="text"
onblur="FormatCheck(event,this)" onkeydown="isBackSpace (event, this)"
onkeyup="this.value = minmaxHH(this.value, 0, 23)" onkeypress="javascript:return
isNumber (event)" onfocus="if(this.value=='HH:MM') this.value='';" placeholder="HH:MM"
maxlength="5" name="gvTimesheetDay1$ctl02$txtSignIn">
I did some analysis on the WebElement: .getSize() returns 0 as height and width, .isDisplayed() returns false, .isEnabled() returns true. Please help me with a path forward as I am out of ideas.
I am trying to write a Java program for my job that logs into Paychex (via Chrome) and downloads reports for me. My code navigates to the website, but I'm stuck at that point. I am using Selenium Chrome web driver, and I am unable to locate the element id for the login field, despite me entering the correct name. I've spent hours trying to figure this out to no avail. I've tried finding the element by id, name, css, and xpath. Nothing has worked! Below is the website url and my code. Any assistance in accessing this element would be beyond appreciated.
Thanks!
WebDriver driver = new ChromeDriver();
driver.get("https://myapps.paychex.com/landing_remote/login.do?TYPE=33554433"
+ "&REALMOID=06-fd3ba6b8-7a2f-1013-ba03-83af2ce30cb3&GUID=&SMAUTHREA"
+ "SON=0&METHOD=GET&SMAGENTNAME=09PZJoiHr8jiAF1z4DL6SopY5OyRzoKSeZ4y"
+ "IhpJe7nkRdeIwtlMrg0rd7X3FRDM&TARGET=-SM-https%3a%2f%2fmyapps%2epa"
+ "ychex%2ecom%2f");
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS)
WebElement id = driver.findElement(By.id("USER"));
HTML :
<input name="USER" class="form-control ng-pristine ng-invalid ng-invalid-required" id="USER" required="" type="text" maxlength="50" placeholder="Enter Username" data-ng-model="user.username" data-payx-form-value="siteminder.username" data-ng-change="clearShowError()" data-payx-focus="">
You do have the correct ID but your desired element is in an IFRAME. Switch to the IFRAME first and then you should be able to access your element.
driver.get("https://myapps.paychex.com/");
driver.switchTo().frame("login");
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("USER"))).sendKeys("MyUsername");
// do stuff but be sure to switch back to default content if you need to access elements outside the IFRAME
driver.switchTo().defaultContent();
I'm trying to create some e-mails via automation but I'm stuck at;
https://app.tutanota.de/#register
<div class="record">
<div class="recordName"></div>
<div class="formAction">
<button class="single fontImage confirm disabled" type="submit" data-bind="css: { disabled: !isCreateAccountPossible() }, lang: 'createAccount_action'">Hesap oluştur</button>
<button class="single" data-bind="fastClick: login, lang: 'backTologin_action'">Giriş'e dön</button>
<label class="recordStatus invalid" data-bind="lang: getCreateAccountErrorMessage()">Lütfen bir şifre giriniz.</label>
</div>
</div>
But I cannot even locate or click this button
<button class="single fontImage confirm disabled" type="submit" data-bind="css: { disabled: !isCreateAccountPossible() }, lang: 'createAccount_action'">Hesap oluştur</button>
I tried with xpath and classname like;
driver.findElement(By.xpath("//button[#type='button' and #class='single fontImage confirm']")).click();
driver.findElement(By.classname("single fontImage confirm"));
and I tried like ;
driver.findElement(By.cssSelector("...(divs and classes until I reach button classname like #somediv .someclass #anotherdiv .anotherclass .single fontImage confirm)"));
Also, this button class is changing when you put informations like mail and password but untill that point its class name is single fontImage confirm disabled after putting informations its class becomes single fontImage confirm
I know this is really basic question but I tried lots of things to get it work but no luck. Any help is appreciated. Thanks !
All your locators are incorrect. The first by.xpath issues are at button type and class. The button type is 'submit' and class should use contains instead of equal. The second by.classname is incorrect because 'disabled' is missing. I don't understand the third cssSelector.
You can use cssSelector:
By.cssSelector("div.formAction > button[class*='single fontImage']");
or XPath:
By.xpath("//div[#class='formAction']/button[contains(#class,'single fontImage')]");
The most convenient way of selecting element by CSS classes is using CSS selector :
div.formAction > button.single.fontImage.confirm
The above selector will find div element with class formAction, and then return child element button containing all but not limited to the following classes: single, fontImage, and confirm.
How do I parse for just the text portions of these blocks of code? I am using Selenium client drivers in java.
<li id="NOT_PUT_PREF_STORE" style="">
<span id="STORE_AVAIL" class="BodyLBoldGrey StockStat">Out of stock</span> <span id="InYourLocal">in your local</span> <span id="storeRollover_2"><span id="STORE_CITY" class="BodyLBoldLtgry VIBSStore1">West Hills</span></span> store<span id="notSelectOptionSOI">.</span>
</li>
or
<li id="NOT_PUT_PREF_STORE" style="">
<span id="STORE_AVAIL" class="BodyLLtgry StockStat">Not carried</span> <span class="BodyLLtgry" id="InYourLocal">in your local</span> <span id="storeRollover_2"><span id="STORE_CITY" class="BodyLBoldLtgry VIBSStore1">West Hills</span></span> store<span id="notSelectOptionSOI">.</span>
</li>
or
<li id="NOT_PUT_PREF_STORE" style="">
<span id="STORE_AVAIL" class="BodyMBold StockStatGreen">In stock</span> <span id="InYourLocal">in your local</span> <span id="storeRollover_2"><span id="STORE_CITY" class="BodyLBoldLtgry VIBSStore1">West Hills</span></span> store<span id="notSelectOptionSOI">.</span>
</li>
I am trying to parse for the text portion in each of these variations in the webelement (ie: Not carried, In stock, Out of stock). I am a very new user to selenium and html parsing so this is really hard for me to get functional.
I was thinking that it would be something like
WebElement driver = new FirefoxDriver(profile);
driver.get(Url);
System.out.println(driver.getElement(By.id("STORE_AVAIL").getText());
Not sure how I would do it with cssSelector but people tell me that is faster.
Would this work?
driver.getElement(By.xpath("//li[#id='NOT_PUT_PREF_STORE']./span[#id='STORE_AVAIL']").getText()
When I try to find elements on the page I always build my locators by:
id = driver.getElement(By.id("STORE_AVAIL").getText());
css selector = driver.getElement(By.css("span#STORE_AVAIL").getText());
xpath = driver.getElement(By.xpath("//span[#id='STORE_AVAIL']").getText());
The id seems to be the fastest and easiest, both for webdriver and for me. id should be unique on the page.
CSS take a little more investigative work on my part, but webdriver handles it just fine.
Lastly, xpath is sometimes unavoidable (unless you buy the devs a beer and ask nicely to change to application so you can locate it faster - after all, you are testing for them anyway). Locating by xpath with IE is terribly slow and writing complex xpaths is a drag.
Xpath is also fragile, one small change to the dom can render your xpath unusable. Then you get to debug/rewrite your xpath (it is as fun as it sounds).
My suggestion is to use Firebug and FirePath addons for Firefox to help you craft your locators.
When you 'View Page Source' it will only show the original HTML source. It will not show changes made by AJAX calls, which looks like how the Walmart page is updating that section/element. This question provides a better explanation.
Assuming you are using Firefox (based on the driver you are using), you can go to the page and click Ctrl+Shift+I to bring up the Inspector tool. Select the element you are interested in. Then click the [HTML] button (in the Inspector menu) to view the current source.
Note that when you are getting the element using selenium webdriver, it will be getting the current value rather than the original value seen in the page source. So you do not have to worry about what you see in the page source.
I am tried with the following html code snipet
<li id="NOT_PUT_PREF_STORE" style="">
<span id="STORE_AVAIL" class="BodyLBoldGrey StockStat">Out of stock</span> <span id="InYourLocal">in your local</span> <span id="storeRollover_2"><span id="STORE_CITY" class="BodyLBoldLtgry VIBSStore1">West Hills</span></span> store<span id="notSelectOptionSOI">.</span>
</li>
I am using the following code to solve it. I get the tree of span elements using XPath and parse through each of it to get the text of the elements.
driver.navigate().to("file:///C:/Users/abc/Desktop/test.html");
List<WebElement> spanEle = driver.findElements(By.xpath("//li/span"));
for (int i = 0; i < spanEle.size(); i++) {
System.out.println(spanEle.get(i).getText());