How to scroll inside form using Selenium - selenium-webdriver

I'm trying to scroll inside form which is displayed in webpage. None of the scroll logic are working using Selenium. I tried to use Actions class as well as JavascriptExecutor, but scroll is not happening.
Steps:
Navigate to https://www.ebay.com/b/Cell-Phones-Smartphones/9355/bn_320094
Click on See All which should display a Form with left hand area scrollable
Code Written:
Using Actions Class:-
WebElement element = waitUntilElementPresent(by);
Actions actions = new Actions(DriverManager.getDriver());
try{
actions.moveToElement(element).click();
actions = actions.sendKeys(Keys.PAGE_DOWN).click();
}catch (Exception e){
e.printStackTrace();
}
Using JavascriptExecutor:-
((JavascriptExecutor) DriverManager.getDriver()).executeScript("window.scrollBy(0,250)");

here is Python version:
driver.maximize_window()
driver.get("https://www.ebay.com/b/Cell-Phones-Smartphones/9355/bn_320094")
driver.find_element(
By.CSS_SELECTOR, "div#mainContent>div:nth-of-type(1) >section:nth-of-type(1) div.b-carousel__seeall>button").click()
wait = WebDriverWait(driver, 30)
wait.until(EC.visibility_of_element_located(
(By.CSS_SELECTOR, "div.x-overlay__body.dialog__body")))
driver.execute_script("arguments[0].scrollIntoView()", driver.find_element(
By.CSS_SELECTOR, "div[data-aspecttitle='location']"))

Related

File upload functionality of Selenium web driver for non-input button without AutoIt or Skuliii

I need to upload a document via Selenium WebDriver using Chromedriver. I have tried all the Action class and JavaScript stuff, but those do not work. I am assuming they do not work because those are relying on the button to be an input field, however, the upload button I'm dealing with is not. It's HTML looks like this:
Steps to reproduce:
Go to: https://www.fedex.com/apps/printonline/#!
Click on View Products under Marketing Material
Click on Get Started under Brochure
Click on Use your File to upload the file
Use Your File
I am able to click the use your file button, but I am not sure how I can upload the file.
driver.get("https://www.fedex.com/apps/printonline/#!");
driver.manage().window().maximize();
driver.manage().deleteAllCookies();
driver.manage().timeouts().pageLoadTimeout(40, TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
//Thread.sleep(6000);
if (driver.findElement(By.xpath("//area[#alt='close']")) != null) {
driver.findElement(By.xpath("//area[#alt='close']")).click();
}
driver.findElement(By.xpath("//a[#title='Marketing Materials']/child::button")).click();
Thread.sleep(1000);
driver.findElement(By.xpath("//a[#title='Get Started - Brochures']")).click();
Thread.sleep(1000);
WebElement element = driver.findElement(By.xpath("//*[#class='btn fxg-btn-orange mycomputer-upload-link']"));
((JavascriptExecutor)driver).executeScript("arguments[0].click()", element);
Ok so first of all get rid of those Thread.sleep(), use fluent wait with polling time, preferably as a function to locate the elements:
private WebElement waitFor(By locator) {
int timeout = 10;
FluentWait<WebDriver> wait = new FluentWait<>(driver)
.pollingEvery(Duration.ofMillis(200))
.withTimeout(Duration.ofSeconds(timeout))
.ignoring(NoSuchElementException.class);
return wait.until((driver) -> driver.findElement(locator));
}
Then you can click the buttons and upload the file like this:
waitFor(By.cssSelector("button.view-products")).click();
waitFor(By.cssSelector("a.get-started")).click();
waitFor(By.cssSelector("a.get-started")).click();
waitFor(By.cssSelector("input.file-upload")).sendKeys("path_to_my_file");
Notice I am using the input element to upload the file - I am not clicking the a link, as you do not need to do that. Just send the path directly to the input element.

Handling print window in selenium webdriver

There is a print button in my application. When I click on the button print windows open with cancel and print button.
I want to click on cancel button in the print window.
I know handling print window is not possible using selenium webdriver alone. I tried using Robot class. But it is not working.
WebDriver driver = (WebDriver) new ChromeDriver();
driver.get("https://www.joecolantonio.com/SeleniumTestPage.html");
driver.manage().window().maximize();
Thread.sleep(2000);
//clicking on the print button
driver.findElement(By.id("printButton")).click();
//print window opens
//creating robot class object
Robot r = new Robot();
r.delay(1000);
r.keyPress(KeyEvent.VK_ESCAPE);
r.keyRelease(KeyEvent.VK_ESCAPE);
The print window opens but nothing happens after that. I was expecting escape button will make the window exit but its does not happens. But manually when I press escape button print window disappears.
Actually you can handle print page window using javascript executor in selenium.
following codes are c#.
If your program is stuck after opening window.print(); which in my case it was happening, try to use the following javascript code instead:
setTimeout(function() { window.print(); }, 0);
this will release your application and you can work with the print page.
then you can switch to the print page simply by the following line:
driver.SwitchTo().Window(driver.WindowHandles.Last());
then you can get the JSPath of any element in print window and interact with it
(IWebElement)js.ExecuteScript($"return {JSPath}").Click();
A complete example of this, is as follows where print window will be opened then the cancel button will be clicked after 2 seconds.
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("setTimeout(function() { window.print(); }, 0);");
driver.SwitchTo().Window(driver.WindowHandles.Last());
Thread.Sleep(2000);
string JSPath = "document.querySelector('body>print-preview-app').shadowRoot.querySelector('#sidebar').shadowRoot.querySelector('print-preview-button-strip').shadowRoot.querySelector('cr-button.cancel-button')";
IWebElement cancelBtn = (IWebElement)js.ExecuteScript($"return {JSPath}");
cancelBtn.Click();
Since the elements in print window exist in the shadow root you cannot select them by selenium web driver that's why I used Javascript Executor to get the cancel button.
Use tab and then click escape.I think it works.
Using Robot is not something I would recommend to handling the print preview page as it will bite you back when you will be running your tests in Parallel mode.
You could click "Cancel" button as follows:
Switch to the Print Preview window using driver.switchTo() function:
driver.switchTo().window(driver.getWindowHandles().stream().filter(handle -> !handle.equals(driver.getWindowHandle())).findAny().get());
Find preview-app Shadow DOM element using i.e. XPath and convert it into a WebElement
WebElement printPreviewApp = driver.findElement(By.xpath("//print-preview-app"));
WebElement printPreviewAppContent = (WebElement) driver.executeScript("return arguments[0].shadowRoot", printPreviewApp);
Find preview-header Shadow DOM element using i.e. CSS and convert into a Selenium's Web Element
WebElement printPreviewHeader = printPreviewAppContent.findElement(By.cssSelector("print-preview-header"));
WebElement printPreviewHeaderContent = (WebElement) driver.executeScript("return arguments[0].shadowRoot", printPreviewHeader);
Locate Cancel button and click it
printPreviewHeaderContent.findElement(By.cssSelector("paper-button[class*=cancel]")).click();
Answer for someone else who still looking solution
To download save as a pdf from the print pop-up window from any web
Add argument
options.addArguments("kiosk-printing");
This will prevent to open any popups from clicking on any print button.But a window dialog folder will open to download the file as a pdf.
Now you need to input the file name and press enter button. For this, we will use the robot class
StringSelection s=new StringSelection("remotePetrol_report.pdf"); // Set the File Name
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(s,null);
//native keystrokes for CTRL, V, and ENTER keys
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);

Hover Electronics -> Mobiles and Click using Selenium in Flipkart UI using Chrome

Actions action = new Actions(driver);
WebElement we = driver.findElement(By.xpath("//*[#id=\"container\"]/div/div[2]/div/ul/li[1]/span"));
action.moveToElement(we).moveToElement(driver.findElement(By.xpath("//*[#id=\"container\"]/div/div[2]/div/ul/li[1]/ul/li/ul/li[1]/ul/li[1]/a[#href='/mobile-phones-store?otracker=nmenu_sub_Electronics_0_Mobiles']"))).click().build().perform();
I am trying to hover and click using xpath. The code is not throwing any error but it is still unable to perform click option after hover.
Try with the below code snippet. I have tested it with chrome driver and works fine.
WebElement electronics_menuname = driver.findElement(By.xpath("//span[contains(text(),'Electronics')]"));
Actions builder = new Actions(driver);
builder.moveToElement(electronics_menuname).build().perform();
WebElement mobile_menu_button = driver.findElement(By.xpath("//li[#class='_1KCOnI _2BfSTw _1h5QLb _3ZgIXy']//a[contains(text(),'Mobiles')]"));
new WebDriverWait(driver,20).until(ExpectedConditions.elementToBeClickable(mobile_menu_button)).click();

Element ... is not clickable at point (35, 37) [duplicate]

I am trying to make some tests using selenium based Katalon Studio. In one of my tests I have to write inside a textarea. The problem is that I get the following error:
...Element MyElement is not clickable at point (x, y)... Other element would receive the click...
In fact my element is place inside some other diva that might hide it but how can I make the click event hit my textarea?
Element ... is not clickable at point (x, y). Other element would receive the click" can be caused for different factors. You can address them by either of the following procedures:
Element not getting clicked due to JavaScript or AJAX calls present
Try to use Actions Class:
WebElement element = driver.findElement(By.id("id1"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().build().perform();
Element not getting clicked as it is not within Viewport
Try to use JavascriptExecutor to bring the element within Viewport:
JavascriptExecutor jse1 = (JavascriptExecutor)driver;
jse1.executeScript("scroll(250, 0)"); // if the element is on top.
jse1.executeScript("scroll(0, 250)"); // if the element is at bottom.
Or
WebElement myelement = driver.findElement(By.id("id1"));
JavascriptExecutor jse2 = (JavascriptExecutor)driver;
jse2.executeScript("arguments[0].scrollIntoView()", myelement);
The page is getting refreshed before the element gets clickable.
In this case induce some wait.
Element is present in the DOM but not clickable.
In this case add some ExplicitWait for the element to be clickable.
WebDriverWait wait2 = new WebDriverWait(driver, 10);
wait2.until(ExpectedConditions.elementToBeClickable(By.id("id1")));
Element is present but having temporary Overlay.
In this case induce ExplicitWait with ExpectedConditions set to invisibilityOfElementLocated for the Overlay to be invisible.
WebDriverWait wait3 = new WebDriverWait(driver, 10);
wait3.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("ele_to_inv")));
Element is present but having permanent Overlay.
Use JavascriptExecutor to send the click directly on the element.
WebElement ele = driver.findElement(By.xpath("element_xpath"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", ele);
I assume, you've checked already that there is no any other component overlapping here (transparent advertisement-iframes or some other component of the DOM => seen quite often such things in input/textfield elements) and, when manually (slowly) stepping your code, it's working smoothly, then ajax calls might cause this behaviour.
To avoid thread.sleep, try sticking with EventFiringWebDriver and register a handle to it.
(Depending on your application's techstack you may work it for Angular, JQuery or wicket in the handler, thus requiring different implementations)
(Btw: This approach also got me rid of "StaleElementException" stuff lots of times)
see:
org.openqa.selenium.support.events.EventFiringWebDriver
org.openqa.selenium.support.events.WebDriverEventListener
driveme = new ChromeDriver();
driver = new EventFiringWebDriver(driveme);
ActivityCapture handle=new ActivityCapture();
driver.register(handle);
=> ActivityCapture implements WebDriverEventListener
e.g. javascriptExecutor to deal with Ajax calls in a wicket/dojo techstack
#Override
public void beforeClickOn(WebElement arg0, WebDriver event1) {
try {
System.out.println("After click "+arg0.toString());
//System.out.println("Start afterClickOn - timestamp: System.currentTimeMillis(): " + System.currentTimeMillis());
JavascriptExecutor executor = (JavascriptExecutor) event1;
StringBuffer javaScript = new StringBuffer();
javaScript.append("for (var c in Wicket.channelManager.channels) {");
javaScript.append(" if (Wicket.channelManager.channels[c].busy) {");
javaScript.append(" return true;");
javaScript.append(" }");
;
;
;
javaScript.append("}");
javaScript.append("return false;");
//Boolean result = (Boolean) executor.executeScript(javaScript.toString());
WebDriverWait wait = new WebDriverWait(event1, 20);
wait.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return !(Boolean) executor.executeScript(javaScript.toString());
}
});
//System.out.println("End afterClickOn - timestamp: System.currentTimeMillis(): " + System.currentTimeMillis());
} catch (Exception ex) {
//ex.printStackTrace();
}
}
As #DebanjanB said, your button (or another element) could be temporarily covered by another element, but you can wait and click it even if you don't know which element is covering the button.
To do this, you can define your own ExpectedCondition with the click action:
public class SuccessfulClick implements ExpectedCondition<Boolean> {
private WebElement element;
public SuccessfulClick(WebElement element) { //WebElement element
this.element = element;
}
#Override
public Boolean apply(WebDriver driver) {
try {
element.click();
return true;
} catch (ElementClickInterceptedException | StaleElementReferenceException | NoSuchElementException e) {
return false;
}
}
}
and then use this:
WebDriverWait wait10 = new WebDriverWait(driver, 10);
wait10.until(elementToBeClickable(btn));
wait10.until(new SuccessfulClick(btn));
Try Thread.Sleep()
Implicit - Thread.Sleep()
So this isn’t actually a feature of Selenium WebDriver, it’s a common feature in most programming languages though.
But none of that matter.
Thread.Sleep() does exactly what you think it does, it’s sleeps the thread. So when your program runs, in the majority of your cases that program will be some automated checks, they are running on a thread.
So when we call Thread.Sleep we are instructing our program to do absolutely nothing for a period of time, just sleep.
It doesn’t matter what our application under test is up to, we don’t care, our checks are having a nap time!
Depressingly though, it’s fairly common to see a few instances of Thread.Sleep() in Selenium WebDriver GUI check frameworks.
What tends to happen is a script will be failing or failing sporadically, and someone runs it locally and realises there is a race, that sometimes WedDriver is losing. It could be that an application sometimes takes longer to load, perhaps when it has more data, so to fix it they tell WebDriver to take a nap, to ensure that the application is loaded before the check continues.
Thread.sleep(5000);
The value provided is in milliseconds, so this code would sleep the check for 5 seconds.
I was having this problem, because I had clicked into a menu option that expanded, changing the size of the scrollable area, and the position of the other items. So I just had my program click back on the next level up of the menu, then forward again, to the level of the menu I was trying to access. It put the menu back to the original positioning so this "click intercepted" error would no longer happen.
The error didn't happen every time I clicked an expandable menu, only when the expandable menu option was already all the way at the bottom of its scrollable area.

How to make selenium 3.4.0 wait for page load?

I am using selenium web driver 3.4.0 to find the response time of a website..In earlier version , I have used
WebDriver wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("myId"))); to find the page loaded.
But these two lines of code not working for version 3.4.0. is there any other way to calculate the load time of a page? Or wait until the page gets loaded? Also I need to detect the modal dialog which will be loaded on button click.
I am implementing using dynamic web project in eclipse IDE.
I also need to wait for some moment until some click event finished loading Dom element. Wait.until() is not working for selenium 3.4.0. how to make selenium wait until some element is visible ?
You can use JavascriptExecutor to get the ready state of the page, and pass it as an expected condition to your wait.until()
Here is the reference code for this,
ExpectedCondition<Boolean> expectation = new
ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor) driver).executeScript("return document.readyState").toString().equals("complete");
}
};
try {
Thread.sleep(1000);
WebDriverWait wait = new WebDriverWait(LocalDriverManager.getDriver(), 30);
wait.until(expectation);
} catch (Throwable error) {
Assert.fail("Timeout waiting for Page Load Request to complete.");
}

Resources