Java Selenium WebDriver unable to place first item into basket - java

Following is short program & in the following web site:
https://uk.webuy.com/search/index.php?stext=*&section=&catid=956
I am trying to click the first three product's "I want to buy this item" button &
view them in the VIEW BASKET at the right side of the page.
For some reason, I am able to see the second and third product only. For some reason, the first product never makes it to the basket, & it does not produce an error.
Only when I change the following line:
allButtons.get(0).click();
to:
allButtons.get(0).click();
allButtons.get(0).click();
allButtons.get(0).click();
I will see one occurrence of the first product in the basket.
What am I doing wrong? Is there something missing that is causing this problem?
Using Java 1.8
Selenium WebDrive Version #2.48
Mac OS Version #10.11.13
Thank you
public class ZWeBuy {
static WebDriver driver;
#Test
public void testProductPurchaseProcess() {
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("https://uk.webuy.com/search/index.php?stext=*&section=&catid=956");
closePopupIfPresent();
//xpath for all product names in this page
List<WebElement> allNames = driver.findElements(By.xpath("//div[#class='searchRecord']/div[2]/h1/a"));
List<WebElement> allButtons = driver.findElements(By.xpath("//div[#class='action']/div/a[2]/div/span"));
System.out.println("Total names = "+ allNames.size());
System.out.println("Total buttons = "+ allButtons.size());
System.out.println("I= " + 0 + " PRDCT: --- " +allNames.get(0).getText());
allButtons.get(0).click();
WebDriverWait wait = new WebDriverWait(driver,120);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("html/body/div[5]/div[1]/div[3]/div[5]/div[1]/div[1]/div[3]/div/a[2]/div/span")));
System.out.println("I= " + 1 + " PRDCT: --- " +allNames.get(1).getText());
allButtons.get(1).click();
System.out.println("I= " + 2 + " PRDCT: --- " +allNames.get(2).getText());
allButtons.get(2).click();
}
public static void closePopupIfPresent(){
Set<String> winIds = driver.getWindowHandles();
System.out.println("Total windows -> "+ winIds.size());
if(winIds.size() == 2){
Iterator<String> iter = winIds.iterator();
String mainWinID = iter.next();
String popupWinID = iter.next();
driver.switchTo().window(popupWinID);
driver.close();
driver.switchTo().window(mainWinID);
}
}
}

Your code isn't functional. Popup closing logic doesn't work, its actually not a separate window, its a dialog box within the same window. You should also consider simplifying your selectors. Alright enough said, here is working and tested code.
WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 30);
driver.get("https://uk.webuy.com/search/index.php?stext=*&section=&catid=956");
WebElement element;
try {
element = driver.findElement(By.cssSelector(".deliver-component-wrapper>a>div"));
System.out.println("Closing pop up");
element.click();
} catch (NoSuchElementException e) {
System.out.println("Alright, no such dialog box, move on");
}
List<WebElement> buyButtons = wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector(
"span.listBuyButton_mx")));
Assert.assertTrue("Less than three buttons found", buyButtons.size() >= 3);
for (int i = 0; i < 3; i++) {
WebElement buyButton = buyButtons.get(i);
wait.until(ExpectedConditions.elementToBeClickable(buyButton)).click();
System.out.println("Clicked Buy Button " + (i + 1));
}
WebElement basketCount = wait
.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#buyBasketRow>td.basketTableCell")));
System.out.println(basketCount.getText());
driver.quit();
It prints
Closing pop up
Clicked Buy Button 1
Clicked Buy Button 2
Clicked Buy Button 3
3 item/s

Your browser could not render that first button. you may put wait.until() method before each click event.
try this
WebDriverWait wait = new WebDriverWait(driver,120);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div[5]/div[1]/div[3]/div[5]/div[1]/div[1]/div[3]/div/a[1]/div/span")));
allButtons.get(0).click();

Related

How to wait till text value is fully loaded in selenium

I tried the following code in Selenium to get the row values.
public static void main(String[] args) throws InterruptedException {
WebDriverManager.chromedriver().setup();
ChromeDriver driver = new ChromeDriver();
driver.get("https://www2.asx.com.au/");
driver.manage().window().maximize();
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
try {
WebElement cookies = driver.findElementByXPath("//button[text()='Accept All Cookies']");
wait.until(ExpectedConditions.elementToBeClickable(cookies)).click();
} catch (Exception e) {
System.out.println("cookies pop up not found");
}
WebElement el = driver
.findElementByXPath("//*[#class='markit-home-top-five aem-GridColumn aem-GridColumn--default--12']");
wait.until(ExpectedConditions.visibilityOf(el));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", el);
List<WebElement> elements = driver.findElementsByXPath("//caption[text()='Gains']//ancestor::table//tr");
for (int i = 1; i <= elements.size(); i++) {
Thread.sleep(2000);
System.out.println(driver.findElementByXPath(
"//caption[text()='Gains']//ancestor::table//tr[" + i + "]//span[#class='value-with-arrow']")
.getText());
}
}
I faced two issues:
The 'Allow all cookies' button is not getting clicked and the pop up remains there. 'cookies pop up not found' is getting printed in the output.
The value of the tables are not getting printed without sleep. in the below output ,it is shown that the first text value is printed as -- as the value was still loading. How to provide till the value is fully loaded.
Thanks in advance!
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("element_id"), "The Text"));
use webdriver wait , you can use expected condition texttobepresent or element to be present
https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html#textToBePresentInElementLocated(org.openqa.selenium.By,java.lang.String)

Closing (dismissing) Chrome print preview with Java + Selenium

My Selenium test looks something like this: customer selects a financial product, fills some necessary data and is presented with terms / agreement document in print preview (as required by local law). After printing / closing the print preview dialog customer enters more data and proceeds further, selects some options and finally gets another print preview of the contract. After that he confirms contract and process is done. I run my tests against Chrome version 75.
So far I've tried two things:
1. Switching to the print preview using Selenium, navigating to the "Cancel" button trough DOM and clicking it. But because the dialog uses shadow DOM it's very ugly, hard to maintain and frequently breaks after Chrome updates.
2. Tried using Robot class from awt, it works well when running locally but fails when running on Selenium grid because Chrome window is not focused and does not receive keyboard events.
Current state of the method handling the closure of print dialog:
public void closePrintPreview() {
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(driver -> driver.getWindowHandles().size() > 1);
driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
wait.until(d -> {
if (d.getWindowHandles().size() > 1) {
d.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
try {
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_ESCAPE);
robot.keyRelease(KeyEvent.VK_ESCAPE);
} catch (AWTException e) {
throw new RuntimeException(e);
}
return false;
}
return true;
});
driver.switchTo().window(driver.getWindowHandles().toArray()[0].toString());
}
So my question would be if there is a simpler way to get the "Cancel" button in print print preview or maybe some way to force the Chrome window to be focused so it can receive key events from Robot?
Here is the solution in python.
You can update the same to work in java.
Python:
def cancelPrintPreview():
# get the current time and add 180 seconds to wait for the print preview cancel button
endTime = time.time() + 180
# switch to print preview window
driver.switch_to.window(driver.window_handles[-1])
while True:
try:
# get the cancel button
cancelButton = driver.execute_script(
"return document.querySelector('print-preview-app').shadowRoot.querySelector('#sidebar').shadowRoot.querySelector('print-preview-header#header').shadowRoot.querySelector('paper-button.cancel-button')")
if cancelButton:
# click on cancel
cancelButton.click()
# switch back to main window
driver.switch_to.window(driver.window_handles[0])
return True
except:
pass
time.sleep(1)
if time.time() > endTime:
driver.switch_to.window(driver.window_handles[0])
break
Java:
public void closePrintPreview() {
String jsCancel = "return document.querySelector('print-preview-app')" +
".shadowRoot.querySelector('#sidebar')" +
".shadowRoot.querySelector('print-preview-header#header')" +
".shadowRoot.querySelector('paper-button.cancel-button')";
WebDriverWait wait = new WebDriverWait(driver, 5);
JavascriptExecutor jse = (JavascriptExecutor) driver;
WebElement cancelButton;
wait.until(driver -> driver.getWindowHandles().size() > 1);
driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[1]);
while (driver.getWindowHandles().size() > 1) {
driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[1]);
cancelButton = (WebElement) jse.executeScript(jsCancel);
cancelButton.click();
}
driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[0]);
}
You can check my answer here for more information on working with shadow-root elements.
Here is the Java implementation based on answer by #supputuri:
public void closePrintPreview() {
String jsCancel = "return document.querySelector('print-preview-app')" +
".shadowRoot.querySelector('#sidebar')" +
".shadowRoot.querySelector('print-preview-header#header')" +
".shadowRoot.querySelector('paper-button.cancel-button')";
WebDriverWait wait = new WebDriverWait(driver, 5);
JavascriptExecutor jse = (JavascriptExecutor) driver;
WebElement cancelButton;
wait.until(driver -> driver.getWindowHandles().size() > 1);
driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[1]);
while (driver.getWindowHandles().size() > 1) {
driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[1]);
cancelButton = (WebElement) jse.executeScript(jsCancel);
cancelButton.click();
}
driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[0]);
}

How to print the elements having common css value in selenium

WebDriver driver = new FirefoxDriver();
driver.get("https://www.ignitionone.com/company/careers/");
driver.manage().window().maximize();
Thread.sleep(2000);
driver.findElement(By.cssSelector("button.teal")).click();
Thread.sleep(2000);
String s2 =driver.findElement(By.cssSelector("#board_title")).getText();
List<WebElement>d_details = driver.findElements(By.cssSelector(".level-0"));
for(int i=0; i<d_details.size();i++){
WebElement element = d_details.listIterator();
String innerhtml = element.getAttribute("innerHTML");
System.out.println("Available openings are" + innerhtml);
}
System.out.println("The title is " + s2);
driver.quit();
This is my code.I am trying to print the available job openings in different areas in the webpage. Can someone please help to understand whats going wring in here.
You have a type casting problem on this line:
WebElement element = d_details.listIterator();
A better way to iterate over the elements would be this:
List<WebElement> results = driver.findElements(By.cssSelector(".level-0"));
for (WebElement result: results) {
String innerhtml = result.getAttribute("innerHTML");
System.out.println("Available openings are" + innerhtml);
}
Note that you may also be experiencing a timing issue. You should replace your Thread.sleep() calls with Explicit Wait commands, check out this topic:
WebDriver - wait for element using Java

Selenium send keys (text), selecting from dropdown and hit enter

I'm trying to trawl this website: http://www.jackson-stops.co.uk/
The data is not showing in the URL so I'm using a chromedriver.
My code is:
public static void main(String[] args) {
//setup chromedriver
File file = new File("C:\\Users\\USER\\Desktop\\chromedriver.exe");
System.setProperty("webdriver.chrome.driver", file.getAbsolutePath());
WebDriver driver = new ChromeDriver();
try {
driver.get("http://www.jackson-stops.co.uk/");
//begin the simulation
WebElement menu = driver.findElement(By.xpath("//*[#id=\"sliderLocation\"]"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", menu);
menu.sendKeys("Knightsbridge");
Thread.sleep(4000);
Select menu2 = new Select(menu);
menu2.selectByVisibleText("Knightsbridge");
Thread.sleep(4000);
} catch (Exception exp) {
System.out.println("exception:" + exp);
//close and quit windows
driver.close();
driver.quit();
}
//close and quit windows
driver.close();
driver.quit();
}
The error that I get is:
exception:org.openqa.selenium.support.ui.UnexpectedTagNameException: Element should have been "select" but was "input"
How would I be able to select a location and hit enter because I tried inspecting the HTML and the options are dynamically loaded so not visible!
You are trying to select an element but it's not select list, it's a link, So all you have to do is to click that element, that's all
First of all pass value
driver.findElement(By.xpath("//*[#id='sliderLocation']")).sendKeys("Knightsbridge")
Once it's done, it populate the values, So You need to click one of option, So you can directly click the element like this(since this population is taking time, you need to use implicit wait
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS))
And then write
driver.findElement(By.xpath("//a[text()='Knightsbridge, London']")).click()
Or if you want to choose the element which consist of Knightsbridge then write the following code and this will choose the first option which consist of Knightsbridge then write
driver.findElement(By.xpath("//a[contains(text(),'Knightsbridge']")).click()
You don't have to use sleep statement anywhere in your selenium code, selenium automatically waits after the click until everything settle down properly. The one exceptional case is, If your page got refreshed after placing the value in your text box(Not necessary for select_list), then you need to use the implicit wait, otherwise even implicit wait is not necessary.
The above code I converted from Ruby to Java, the original code which I used to check is from selenium Ruby binding, the code is below
#driver.find_element(:xpath, "//*[#id='sliderLocation']").send_keys "Knightsbridge"
#driver.manage.timeouts.implicit_wait = 10
#driver.find_element(:xpath, "//a[contains(text(),'Knightsbridge')]").click
#driver.find_element(:xpath, "//a[text()='Knightsbridge, London']").click
You can do as below:
String requiredCity = "London";
List<WebElement> menu2 = driver.findElements(By.xpath("//ul[#id='ui-id-3']/li"));
System.out.println("Total options: "+menu2.size());
for(int i=0;i<menu2.size();i++)
{
String CurrentOption = menu2.get(i).getText();
if(CurrentOption.contains(requiredCity)){
System.out.println("Found the city : "+CurrentOption);
menu2.get(i).click();
}
}
This is the full solution using Ranjeet's answer.
File file = new File("C:\\Users\\USER\\Desktop\\chromedriver.exe");
System.setProperty("webdriver.chrome.driver", file.getAbsolutePath());
WebDriver driver = new ChromeDriver();
try {
driver.get("http://www.jackson-stops.co.uk/");
//begin the simulation
WebElement menu = driver.findElement(By.xpath("//*[#id=\"sliderLocation\"]"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", menu);
menu.sendKeys("London");
Thread.sleep(4000);
String requiredCity = "London";
List<WebElement> menu2 = driver.findElements(By.xpath("//ul[#id='ui-id-3']/li"));
System.out.println("Total options: " + menu2.size());
for (int i = 0; i < menu2.size(); i++) {
String CurrentOption = menu2.get(i).getText();
if (CurrentOption.contains(requiredCity)) {
System.out.println("Found the city : " + CurrentOption);
menu2.get(i).click();
Thread.sleep(6000);
menu.sendKeys(Keys.RETURN);
}
}
Thread.sleep(8000);
} catch (Exception exp) {
System.out.println("exception:" + exp);
//close and quit windows
driver.close();
driver.quit();
}
//close and quit
driver.close();
driver.quit();
WebElement selectMyElement = driver.findElement((By.xpath("//div/select/option[#value='Your value']")));
selectMyElement.sendKeys("Your value");
Actions keyDown = new Actions(myLauncher.getDriver());
keyDown.sendKeys(Keys.chord(Keys.DOWN, Keys.DOWN)).perform();

Handling window in Selenium WebDriver using Java

While automating via Selenium WebDriver, I have the below scenario.
On a window I click on a button. Code will do the query to DB and display a window with its findings.
I am unable to switch to the new window.
The parent window is closed on clicking the button and I am not able to switch to the new window, since the control is on the parent window and it is not visible on the screen.
Can someone please help me with this.
Thanks
My code is as follow:
driver.findElement(By.xpath(".//*[#id='WIN_0_560700305']/div/div")).click();
window1=driver.getWindowHandle();
driver.switchTo().window(window1);
System.out.println(driver.getTitle());
windowList = driver.getWindowHandles();
System.out.println("Number of Windows-->" + driver.getWindowHandles().size());
iterator = windowList.iterator();
String window2 = null;
while(iterator.hasNext())
{
System.out.println("Entering while loop");
window2 = (String)iterator.next();
System.out.println(driver.getTitle());
}
if (!(window1.equals(window2))){
driver.switchTo().window(window2);
System.out.println("Title of the page after - switchingTo: " +
driver.getTitle());
System.out.println("Current url" + driver.getCurrentUrl());
driver.manage().window().maximize();
}
driver.findElement(By.xpath(".//*[#id='WIN_0_540000016']/div/div")).click();
I have modified your code a little bit, try with the code below, Hope it will work.
String window1=driver.getWindowHandle();
driver.findElement(By.xpath(".//*[#id='WIN_0_560700305']/div/div")).click();
System.out.println(driver.getTitle());
Set windowList = driver.getWindowHandles();
Iterator iterator = windowList.iterator();
String window2 = null;
while(iterator.hasNext())
{
System.out.println("Entering while loop");
window2 = iterator.next().toString();
if(!(window1.equals(window2))){
driver.switchTo().window(window2);
System.out.println("Title of the page after - switchingTo: " +
driver.getTitle());
System.out.println("Current url" + driver.getCurrentUrl());
driver.manage().window().maximize();
}
}
//Switched to new window, do operations in new window ..

Categories