My code begins by signing me into PayPal, then signing into eBay and navigating to the pay fees page, then checking out with PayPal. The final "Continue" button I can't click/submit. I've tried by xpath, id and class. I even tried sending TAB 7x until the Continue button and then sending Enter but that didn't work.
I have found this discussion but I'm not sure how to make it work for me.
PayPal Sandbox checkout 'continue button' - Unable to locate element: - C# WebDriver
Here's a screenshot of the PayPal code and page I'm trying to do.
//Chrome WebDriver specific
System.setProperty("webdriver.chrome.driver", "C:\\automation\\drivers\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize(); //maximise webpage
WebDriverWait wait = new WebDriverWait(driver, 20);
//navigate to Paypal
driver.get("https://www.paypal.com/uk/signin");
//wait 2.5s for the page to load
try {
Thread.sleep(2500);
}
catch (Exception e) {
e.printStackTrace();
}
WebElement paypalEmail = driver.findElement(By.id("email"));
paypalEmail.sendKeys("******");
//wait 2.5s for the page to load
try {
Thread.sleep(2500);
}
catch (Exception e) {
e.printStackTrace();
}
WebElement paypalSubmit = driver.findElement(By.id("btnNext"));
paypalSubmit.click();
String URL = ("https://www.paypal.com/uk/signin");
driver.get(URL);
WebElement form2 = driver.findElement(By.cssSelector(".main form"));
WebElement username = form2.findElement(By.id("password"));
username.sendKeys("******");
WebElement paypalSubmit2 = driver.findElement(By.id("btnLogin"));
paypalSubmit2.click();
//navigate to Ebay
driver.get("https://signin.ebay.co.uk/ws/eBayISAPI.dll?SignIn&ru=https%3A%2F%2Fwww.ebay.com%2F");
// Enter user name , password and click on Signin button
WebElement form = wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#mainCnt #SignInForm")));
form.findElement(By.cssSelector("input[type=text][placeholder='Email or username']")).sendKeys("******");
form.findElement(By.cssSelector("input[type=password]")).sendKeys("******");
form.findElement(By.id("sgnBt")).click();
driver.get("http://cgi3.ebay.co.uk/ws/eBayISAPI.dll?OneTimePayPalPayment");
//WebElement Pay =
driver.findElement(By.xpath("//input[#value='Pay']")).click();
WebDriverWait wait2 = new WebDriverWait(driver, 15);
wait2.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[#id=\"confirmButtonTop\"]")));
driver.findElement(By.xpath("//*[contains(#id,'confirmButtonTop')]")).click();
}
}
Based on your given screenshot one of following should work to click on continue button :
Method 1 :
WebElement paypalSubmit = driver.findElement(By.xpath("//input[#data-test-id='continueButton']"));
paypalSubmit.click();
Method 2:
By paypalButton=By.xpath("//input[#data-test-id='continueButton']"));
WebElement element=driver.findElement(paypalButton);
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].scrollIntoView(true);",element);
js.executeScript("arguments[0].click();", element);
Try 2nd method if you feel your button require bit scroll to bottom to get clickable.
one more xpaths you can use for button if above don't work :
//input[#value='Continue' and #id='confirmButtonTop']
In my experience, paypal likes to use iFrames. If that's true in your case, that means unless you tell webdriver to switch frame contexts, that paypal form will be unavailable to you regardless of your xpath/css selectors.
You can get a list of all available frames currently loaded with this code:
String[] handles = driver.getWindowHandles()
Your actual page will always be the 0th index in that returned array. If paypal is your only iFrame, then you can target the 1th index. Here's a possible solution to that:
String mainPageHandle = handles[0];
String paypalHandle = handles[1];
driver.switchTo().window(paypalHandle);
// Do paypal interactions
driver.switchTo().window(mainPageHandle);
// Back to the main page
There are definitely more robust ways to handle this, and if your page unfortunately has more than one iFrame, then you may need to do more to verify which handle is which, such as test the presence of an element you know is contained within. In general, the frames will load in the same order every time. As a golden path to this problem, this will get you in and out of that iFrame to perform work.
Sometimes the conventional click() doesn't work. In that case, try using the Javascript Executor Click as below.
Make sure you import this class
org.openqa.selenium.JavascriptExecutor
And use this instead of click();
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", driver.findElement(By.xpath(“//input[#data-test-id='continueButton']”)));
Try this and let me know if this works for you.
Related
I'm currently using Selenium for one of my academic assignments regarding quality assurance automation. For this, I'm using a website that is not handled by me or anyone I know.
I have noticed that when I run my test cases, sometimes, advertisements appear on the website in the Chrome window that opens up. Since it is not a pop-up, using disable-popup-blocking does not work. Moreover, since the advertisement doesn't always appear, using a code segment to close the advertisement modal doesn't work either.
The following image depicts an example scenario.
Is there a workaround for this issue? Thank you in advance!
#Test
#Order(2)
public void CovertLang() throws InterruptedException {
// Navigating to 123apps.com website
driver.get("https://123apps.com/");
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
// Accessing the language modal
WebElement langButton = driver.findElement(By.id("language-link"));
langButton.click();
// Wait until the modal opens
wait.until(ExpectedConditions
.visibilityOfElementLocated(By.className("modal-title")));
// Selecting German as the language
WebElement deutschButton = driver.findElement(By.xpath("//a[#href='/de/']"));
deutschButton.click();
Thread.sleep(1000);
// Comparing the web URL
String newURL = driver.getCurrentUrl();
assertEquals("https://123apps.com/de/", newURL);
}
The above shows an example of a test I conducted.
You can disable that ad using the below js code:
// Selecting German as the language
WebElement deutschButton = driver.findElement(By.xpath("//a[#href='/de/']"));
deutschButton.click();
Thread.sleep(1000);
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("const elements = document.getElementsByClassName('adsbygoogle adsbygoogle-noablate'); while (elements.length > 0) elements[0].remove()");
deutschButton.click();
// Comparing the web URL
String newURL = driver.getCurrentUrl();
assertEquals("https://123apps.com/de/", newURL);
I have this react application being tested using selenium webdriver.
if my login is wrong, how do i detect the text using selenium webdriver? I am unable to find the code/ figure out how to trap the pop up message . 'authentication failed'
#Test
public void failed_login() {
System.setProperty("webdriver.chrome.driver",
"C:\\Users\\rahul\\Downloads\\chromedriver_win32_83\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
driver.get("http://testingapp.workspez.com");
driver.manage().window().maximize();
WebElement username = driver.findElement(By.id("field_email"));
WebElement password = driver.findElement(By.id("field_password"));
WebElement login = driver.findElement(By.xpath("//*[text()='Log In']"));
username.sendKeys("wrongemail#gmail.com");
password.sendKeys("wrongpassword");
login.click();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
driver.manage().timeouts().implicitlyWait(120, TimeUnit.SECONDS);
String url = driver.getCurrentUrl();
assertEquals(url, "http://testingapp.workspez.com/login");
}
You can use below code to verify if authentication failed pop up is displayed or not:
List<WebElement> popUpElement = driver.findElements(By.id("client-snackbar");
if(popUpElement.size() != 0){
System.out.println("Pop up is Present "+popUpElement.get(0).getText());
}else{
System.out.println("Pop up is Absent");
}
After you perform click, you can use Explicit Wait:
try{
WebDriverWait wait = new WebDriverWait(driver, 10); //10 seconds
WebElement messageElement = wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.xpath("//*[#id = 'client-snackbar']")
)
);
//if reach here, means the error is visible.
System.out.println(messageElement.getText());
}catch(TimeoutException ignored){
//if trigger timeoutexception
//that means the element with message is not visible, that means no error
}
This will wait 10 seconds for the element to be visible.
If it is not visible, it will throws TimeoutException which you can simply ignore.
That means the error was not visible in first 10 seconds after click.
You can change the time with whatever you want.
You can find the locator for that toast message.
For locating web element
Go to your login.
Enter your invalid credentials.
Press F12 and go to console/Sources
Click on login to get your message.
Press F8 to pause it. Now you can inspect your element.
So from webelement you can fetch text with gettext() method.
You can apply explicit wait to wait for your error message.
I have problem to automate this drop down using selenium web driver using Java
This is the link - Go to 5th drop down named as Github users (fetch. js)
I am not able to enter the data into search field.
I am using send keys after perform click but it throws an exception like this " element is not interact able"
Steps I follow
driver.findElement(By.xpath("xapth")).click
drop down opens with no options because it is searchable and options are coming dynamically after entering key word into the search field.
driver.findElement(By.xpath("xapth")).sendkeys("Test");
Sendkeys are not working in this case because of drop down closed when perform send keys action.
<div class="Select-placeholder">Select...</div>
Below is the code which is working.
Please do optimize the code by removing thread.Sleep and putting some meaningful waits as per your requirement.
driver.Navigate().GoToUrl("https://jedwatson.github.io/react-select/");
IWebElement element1 = driver.FindElement(By.XPath("//span[#id='react-select-6--value']"));
IWebElement element2 = driver.FindElement(By.XPath("//span[#id='react-select-6--value']/div[2]/input[1]")) ;
element1.Click();
Thread.Sleep(2000);
element2.SendKeys("Test");
Thread.Sleep(1000);
element2.SendKeys(Keys.Tab);
Please note that element2 gets activated once you click on element1.
Try the following code:
public void typeAndSelect() {
WebElement searchBox = driver.findElement(By.xpath("//div[#class='section'][5]//div[#class='Select-control']"));
searchBox.click();
WebElement inputField = driver.findElement(By.xpath("//div[#class='section'][5]//input[#role='combobox']"));
inputField.clear();
String searchWord = "test";
inputField.sendKeys(searchWord);
WebElement selectDropdown = driver.findElement(By.xpath("//div[#class='Select-menu-outer']//div[#role='option'][text()='" + searchWord +"']"));
// wait for search results.
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(selectDropdown)).click();
}
Correct the following xpath part
"//div[#class='section'][5]"
to your implementation of the dropdown
I am able to click on sign in link in the start page [a link] http://imgur.com , resulting modal window of username and password field. while I was trying to extract password field on the resulted page, found no elements of username and password fields. Even I checked the source code at that instant using driver.getPageSource(); and there is no sign of username or password elements. Following is the code used to extract password field from the specified URL.
pwd = driver.findElement(By.cssSelector("input[type='password']"));
code for clicking the modal window is
driver.findElement(By.partialLinkText("sign in")).click();
Later I found that they are using iframes so I started searching the password fields in each iframe as shown below.
List<WebElement> iFrames = null;
WebElement iFramePwd=null;
iFrames = driver.findElements(By.tagName("iframe"));
if (iFrames.size() > 0) {
for (int l = 0; l < iFrames.size(); l++) {
try{ driver.switchTo().frame(l);
}
catch(NoSuchFrameException ljn){
System.out.println(ljn);
driver.switchTo().defaultContent();
continue;
}
try {
try{
iFramePwd = driver.findElement(By.cssSelector("input[type='password']"));
}
catch(NoSuchElementException lkn){
System.out.println(lkn);
driver.switchTo().defaultContent();
continue;
}
Size of iframes displaying as 5 but when i try to switch to the iFrame iam always getting NoSuchFrameException.
Please visit the specified URL for analyzing the source code. I dont know where i am missing the point. Is there any way to get password field from the modal window. Any help would be greatly appreciated. Thanks in advance
Try this code
WebDriver driver = new FirefoxDriver();
driver.get("http://imgur.com/");
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.findElement(By.partialLinkText("sign in")).click();
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.className("cboxIframe")));
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("f")));
driver.findElement(By.name("username")).sendKeys("abcd");
driver.findElement(By.xpath(".//*[#id='password']/input")).sendKeys("abcd");
driver.close();
driver.quit();
If we use loop to reach the iframe, there is a problem. You don't know which ifrmae you are in because List of web elements does not grantee the exact sequence of iframe in page. For Example below code is not working and showing error "Element belongs to a different frame than the current one - switch to its containing frame to use it"
List<WebElement> my_iframes = driver.findElements(By.tagName("iframe"));
// moving to inner iframe
if(my_iframes.size() > 0){
for(WebElement my_iframe : my_iframes){
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(my_iframe));
}
}
driver.findElement(By.name("username")).sendKeys("abcd");
driver.findElement(By.xpath(".//*[#id='password']/input")).sendKeys("abcd");
I have written below code to drag an element and add it in workspace. There is no error in console window however drap drop is not performed on chrome browser.
WebElement dragElement = driver.findElement(By.xpath("//*[#id='sidebar-wrapper']/div/div/nginclude/div[2]/accordion/div/div[1]/div[2]/div/div/div[1]/div[2]"));
Thread.sleep(4000);
System.out.println("Element Selected to Drag");
WebElement dropElement = driver.findElement(By.xpath("//*[#id='workspace']/div/div/div/div[2]/div/div/div/div[2]/span"));
Thread.sleep(4000);
act.clickAndHold(dragElement).moveToElement(dropElement).release().build().perform();
I have tried multiple times but not able to succeed. Please provide your inputs
You can try give the location of the element
act.clickAndHold(dragElement).perform();
act.moveToElement(dropElement, dropElement.getLocation().getX(), dropElement.getLocation().getY()).perform();
act.release(dropElement).perform();
This is another method provided in the Selenium documentation here: http://www.seleniumhq.org/docs/03_webdriver.jsp#drag-and-drop.
WebElement dragElement = driver.findElement(By.xpath("//*[#id='sidebar-wrapper']/div/div/nginclude/div[2]/accordion/div/div[1]/div[2]/div/div/div[1]/div[2]"));
WebElement dropElement = driver.findElement(By.xpath("//*[#id='workspace']/div/div/div/div[2]/div/div/div/div[2]/span"));
(new Actions(driver)).dragAndDrop(dragElement, dropElement).perform();
You can use below code for drag and drop but I suggest you to optimize your xpath. It might be the real problem for you.
WebElement source = driver.findElement(By.xpath("//*[#id='sidebar-wrapper']/div/div/nginclude/div[2]/accordion/div/div[1]/div[2]/div/div/div[1]/div[2]"));
Thread.sleep(4000);
System.out.println("Element Selected to Drag");
WebElement target = driver.findElement(By.xpath("//*[#id='workspace']/div/div/div/div[2]/div/div/div/div[2]/span"));
Thread.sleep(4000);
Actions builder = new Actions(driver);
Action mouseOverHome = builder.dragAndDrop(source, target).build();
mouseOverHome.perform();
I had a similar issue in Firefox and resolved it by adding an extra movement instruction in front of the moveToElement() instruction, like this:
private void dragAndDrop(WebElement element, WebElement target) {
Actions builder = new Actions(driver);
builder.clickAndHold(element);
builder.moveByOffset(20,20); // THIS was the critical part for me
builder.moveToElement(target);
builder.release();
builder.perform();
}