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();
Related
I tried to locate an element with id.
The Developer tools shows this:
<input aria-invalid="false" autocomplete="off" placeholder="Partner name" type="text" class="MuiInputBase-input MuiInput-input MuiAutocomplete-input MuiAutocomplete-inputFocused MuiInputBase-inputAdornedEnd" aria-autocomplete="list" autocapitalize="none" spellcheck="false" value="" id="mui-85700">
The id always changing every time I reload the page.
I think I find a solution to locate the element:
findElement(By.xpath("//*[contains(#id,'mui')]")).click();
But now I get the following error:
(org.openqa.selenium.ElementClickInterceptedException: Element <p id="mui-51640" class="MuiTypography-root MuiTablePagination-caption MuiTypography-body2 MuiTypography-colorInherit"> is not clickable at point (1124,747) because another element <div class="MuiDialog-container MuiDialog-scrollPaper"> obscures it
How can I solve it?
Side note:
In developer tool I see 4 web elements which contains "mui" String.
On the page I only see 2 web elements: one with <input id="mui85700"...> and another one is <label id="mui85700"...>
As before I said I need the input id field.
The <input> element is a React InputBase component and a dynamic element and the trailing dynamic value of the id attribute will will get changed everytime you access the application afresh. So you have to construct a dynamic locator strategy.
Solution
To click on the <input> element you need to induce WebDriverWait for the elementToBeClickable() and you can use either of the following locator strategies:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("input.MuiInputBase-input.MuiInput-input.MuiAutocomplete-input.MuiAutocomplete-inputFocused.MuiInputBase-inputAdornedEnd[id^='mui'][placeholder='Partner name']"))).click();
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[#class='MuiInputBase-input MuiInput-input MuiAutocomplete-input MuiAutocomplete-inputFocused MuiInputBase-inputAdornedEnd' and starts-with(#id, 'mui')][#placeholder='Partner name']"))).click();
You may use findElements and get all the elements form web page
Use a loop and check if the element is visible or element is clickable. This is solve your issue.
you can use like this,
List<WebElement> products = driver.findElements(By.xpath("xpath"));
for (int i=0; i<products.size(); i++){
String name = products.get(i).getText();
System.out.println(name);
if(name.containsAll('text')) {
driver.findElements(By.xpath("xpath")).get(i).click();
}
}
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()
I am using Selenium Webdriver and working on automating an AngularJS Web App on Chrome. It was going pretty well until I hit a dropdown list on the app.
My test keeps crashing everytime I try to select a value from it. I have been doing my research on this and I have only seen 2 solutions (both of which I have tried but don't work)
Use the Select object. This doesn't work because the html tag is not <select>, its <md-select> and this fails the test.
I then tried to just click on the dropdown element and click on the value - driver.findElement(By.xpath("xpath to dropdown list")).click(); and driver.findElement(By.xpath("xpath do dropdown value")).click();
With example 2, I also tried creating it as a WebElement variable and calling click() separate, but this did not work either.
Any ideas on how I can solve this issue?
Update
HTML for the dropdown list
<div ng-switch-when="dropdown" class="ng-scope">
<zf-form-dropdown>
<div class="dropdown">
<div layout="row">
<div flex="50" class="quote-label">
<p ng-bind-html="::label" class="ng-binding">Title</p>
</div>
<div ng-show="false" flex="10" class="tooltip-icon ng-hide" ng-click="showToolTip(field.get('toolTip'))" role="button" tabindex="0" aria-hidden="true"><img src="img/item-question#2x.png"></div>
<md-select flex="" ng-disabled="quote.isRated() || !input.enabled" ng-change="onDropdownChange()" ng-model="input.value" class="ng-valid md-default-theme ng-touched ng-dirty" role="combobox" id="select_0Q9" aria-haspopup="true" aria-expanded="false" aria-labelledby="select_label_0I1" tabindex="0" aria-disabled="false" aria-invalid="false" aria-owns="select_menu_0Q8"><md-select-label class="md-select-label md-placeholder" id="select_label_0I1"><span></span><span class="md-select-icon" aria-hidden="true"></span></md-select-label></md-select>
</div>
</div>
</zf-form-dropdown>
</div>
HTML for the value I want to select
<md-option ng-value="::item.val" ng-selected="item.checked" ng-repeat="item in getOpts()" tabindex="0" class="ng-scope" role="option" aria-selected="false" id="select_option_0QD" value="MR">
<div class="md-text ng-binding">Mr</div>
<div class="md-ripple-container"></div>
</md-option>
The xpath for the dropdown list is //*[#id="select_0Q9"]
The xpath for the dropdown value is //*[#id="select_option_0QD"]
If you are sure that your Xpath is fine then you can also click using javascriptexecutor so try it out like below:-
WebElement element= driver.findElement(By.xpath("//md-option[#id='select_option_0QD']/div[1]"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", element);
Please feel free to locate the element in above code as per your convenience .
As per me your xpath of dropdown should be like below:-
//md-option[#id='select_option_0QD']
And xpath of first div which I suppose want to click is:-
//md-option[#id='select_option_0QD']/div[1]
Change [1] to [2] if you want 2nd value.
In an another aspect you can also store all your element in the list(As you know you can't use select) and click them as per your need or all.
For that you need to use xpath like:-
//md-option[#id='select_option_0QD']/div
Now implement it into code:-
List<WebElement> allelemts = driver.findElements(By.xpath("//md-option[#id='select_option_0QD']/div"));
for(WebElement ele: allelemts){
driver.findElement(By.xpath("//md-option[#id='select_option_0QD']")).click();
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", ele);
}
Hope it will help you :)
Since you are receiving a NoSuchElementException exception, I believe the issue lies in Selenium not able to identify the element. Try any of the following wait methods and then try to click the element.
Explicit Wait: (Most Preferred)
WebDriverWait wait = new WebDriverWait(driver, 20);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("elementID")));
or
WebDriverWait wait = new WebDriverWait(driver, 20);
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("elementID")));
Implicit Wait:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Sleep: (Try to avoid this unless absolutely necessary)
Thread.sleep(1000);
EDIT: Added code to check for element's presence using findElements method.
Before using any of these wait methods you could also check for the presence of your element using findElements method.
List<WebElement> element = driver.findElements(By.id("elementId"));
if (element.size() == 0) {
System.out.println("Element not found");
} else{
System.out.println("Element found");
}
I have finally solved the issue!
I got the Selenium IDE and recorded a session where I got as far as selecting the dropdown menu and selecting my value. I then exported the file as a java test case and was able to read the lines where it selected the values, and they were;
driver.findElement(By.cssSelector("#select_08D > #select_label_005 > span.md-select-icon")).click();
driver.findElement(By.id("select_option_08H")).click();
So first off they both do not use xpath to find the elements, the dropdown menu itself is found with the cssSelector and the value is found by the id.
I am just cross referencing again and the id for the value is select_option_08H but while I am looking at Google Console I can see the id for the value is select_option_189
I'm studying Selenium WebDriver and testing my skills on a public site. The issue is that I cannot interact with input element with role='combobox' using Selenium WebDriver + Java.
I need to interact (select 2d option) for the first element of calculator ("Калькулятор"-"Тип расчета" - combobox near this text). Firefox shows the code for it:
<div class="select2-search">
<label class="select2-offscreen" for="s2id_autogen2_search"></label>
<input id="s2id_autogen2_search" class="select2-input" type="text" aria-autocomplete="list" aria-expanded="true" role="combobox" spellcheck="false" autocapitalize="off" autocorrect="off" autocomplete="off" aria-owns="select2-results-2" placeholder="" aria-activedescendant="select2-result-label-17"></input>
When I try to click or sendkeys for it it writes that element (both selects and selects2) is not visible although it is visible and interactable manually. CSS is not transformed. I found that JS can change property to make the element visible, but I tried - and nothing changed, isDisplayed() shows false and I cannot select 2d item of the combobox.
Here is the code (I have left only main part)):
WebDriver driver = new FirefoxDriver();
driver.get("http://sberbank.ru/ru/person/credits/money/consumer_unsecured");
try{
Thread.sleep(1500);
}catch(Exception e)
{System.out.println("Error in Sleep.");}
List<WebElement> selects = driver.findElements(By.cssSelector(".select2-search"));//(".select2-results"));
List<WebElement> selects2 = driver.findElements(By.xpath("//input[#class='select2-input']"));
System.out.println("xpath: "+selects2.size());
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("window.scrollTo(0,1000);");
System.out.println("value:"+selects2.get(0).getAttribute("value"));
((JavascriptExecutor) driver).executeScript("arguments[0].style.display='inline';arguments[0].style.visibility='visible';arguments[0].style.height = '20px';arguments[0].style.width = '80px';",selects2.get(0));
System.out.println("visible: "+selects2.get(0).isDisplayed());
System.out.println("enabled: "+selects2.get(0).isEnabled());
System.out.println("height: "+selects2.get(0).getAttribute("height")+",width: "+selects2.get(0).getAttribute("width"));
selects2.get(0).click();
selects2.get(0).sendKeys("По среднемесячному доходу");
It writes:
xpath: 7
value:
visible: false
enabled: true
height: 0,width: 0
Exception in thread "main" org.openqa.selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with
I also tried to trigger keyevent with JQuery but it didn't help:
((JavascriptExecutor) driver)
.executeScript("var s=window.document.createElement('script');" +
"s.src='D:\\Data\\Selenium\\jquery-1.11.3.min.js';" +
"window.document.head.appendChild(s);");
((JavascriptExecutor)driver).executeScript("arguments[0].focus();var e = jQuery.event.trigger({ type : 'keypress', which : 65 });arguments[0].trigger(e);", selects2.get(0));
It writes "Exception in thread "main" org.openqa.selenium.WebDriverException: arguments[0].trigger is not a function"
Please help me to fix my code to be able to set 2d item of this combobox.
Finally got it working -
driver.get('http://sberbank.ru/ru/person/credits/money/consumer_unsecured')
driver.find_element_by_xpath('//*[#id="s2id_autogen1"]/a').click()
driver.find_element_by_xpath('//ul[#class="select2-results ps-container"]/li[2]').click()
In order to avoid window dialog of upload file, I'm trying following:
driver.findElement(By.xpath("//span[#class='ab-attachment-item']/input")).sendKeys(filePath);
Following is the HTML code snippet:
<div class="ab-attachments">
<span class="ab-attachment-item" ng-hide="isReadOnly()" style="background-color: transparent;">
<input class="ab-attachment-input ng-isolate-scope firefinder-match" type="file" rx-file-upload="file" accept=".pdf,image/*" style="background-color: transparent;">
But it results into error:
org.openqa.selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with
I want to confirm if this error is because of ng-hide="isReadOnly()" in span tag?
And how this can be resolved using Selenium WebDriver itself(using JavaScriptExecutor or something)?
For handling this dialog other tools like Sikuli, AutoIt can be used; but I want to avoid that overhead.
You should be able to do this:
driver.findElement(By.className("ab-attachment-input ng-isolate-scope firefinder-match")).sendKeys(filePath);
If not try adding an implicit wait before you try and sendKeys
Int timeoutInSeconds = 10;
WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("ab-attachment-input ng-isolate-scope firefinder-match"));
//I would use implicit wait and directly call the input element instead
new WebDriverWait(driver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("[rx-file-upload='file'][accept=".pdf,image/*"]"))).sendKeys("filePathWithExtension");