How to Test Print-preview of Chrome browser using Chrome webdriver? - selenium-webdriver

I have tried using switching between windows using
String winHandleBefore = driver.getWindowHandle();
<code to print>
for (String winHandle : driver.getWindowHandles())
driver.switchTo().window(winHandle);
driver.findElement(By.className("cancel")).click();
driver.switchTo().window(winHandleBefore);
This hangs my test case execution after it opens the print preview page.
Also tried with javascript executor method, but no use.
JavascriptExecutor jse = (JavascriptExecutor) driver;
jse.executeScript("window.close()", "");
Please suggest if it's possible to do so.

I have found the answer to my question. I used below code snippet.
//Create a Region for Desktop Screen
ScreenRegion s = new DesktopScreenRegion();
//Find target with below Image in Desktop Screen
Target target = new ImageTarget(new File("Image.png"));
ScreenRegion r = s.find(target);
// Create a mouse object
Mouse mouse = new DesktopMouse();
// Use the mouse object to click on the center of the target region
mouse.click(r.getCenter());
With the help of this snippet you would able to find the print or cancel and do the mouse click event and proceed with selenium tests. This was possible using sikuli API

Related

Element is not clickable at point ... error when using headless browsing

I have this error "org.openqa.selenium.ElementClickInterceptedException: element click intercepted: Element is not clickable at point (209, 760)", when I run the piece of code below in headless mode. When it is run with browser displayed I have no error and test passes fine. As you can see below, I trie with waiting, js executor, actions move to element but still no good result. I am using xpath to locate / define the element, and not coordinates. Why is this happening please and how can I solve it? Thanks in advance.
#Test(priority = 1)
public void verifyAddUserWithMarkedMandatoryFields() {
// accessing add user webpage / functionality
userListObject.getAddUserButton().click();
// inserting data to complete form
addOrEditUserPageObject.insertCredentials(userModel.getUsername(), userModel.getEmail(), "", userModel.getPassword());
// clicking Submit when becoming enabled
WebDriverWait myWaitVariable = new WebDriverWait(driver, 5);
myWaitVariable.until(ExpectedConditions.elementToBeClickable(addOrEditUserPageObject.getSubmitButtonAddOrEdit()));
// Actions actions = new Actions(driver);
// actions.moveToElement(addOrEditUserPageObject.getSubmitButtonAddOrEdit()).click().perform();
JavascriptExecutor jse = (JavascriptExecutor)driver;
// jse.executeScript("scroll(209, 760)"); // if the element is on top.
jse.executeScript("scroll(760, 209)"); // if the element is on bottom.
addOrEditUserPageObject.getSubmitButtonAddOrEdit().click();
}
You should add screen size for the headless mode, something like this:
Map<String,String> prefs = new HashMap<>();
prefs.put("download.default_directory", downloadsPath); // Bypass default download directory in Chrome
prefs.put("safebrowsing.enabled", "false"); // Bypass warning message, keep file anyway (for .exe, .jar, etc.)
ChromeOptions opts = new ChromeOptions();
opts.setExperimentalOption("prefs", prefs);
opts.addArguments("--headless", "--disable-gpu", "--window-size=1920,1080","--ignore-certificate-errors","--no-sandbox", "--disable-dev-shm-usage");
driver = new ChromeDriver(opts);
I put much more things here, the only relevant point here is "--window-size=1920,1080", this should resolve your problem.
The rest is to show how things are managed, including other relevant settings for headless mode.

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);

unable to take screenshot of mouseover in selenium

I am trying to take screenshot of sub menu which happens on hovering in selenium using TakesScreenshot. But this is not working. Screenshot is taken but sub menu is not present in the image.
I have also tried using implicit wait after hover, but nothing worked.
Please suggest a method to capture screenshot of the sub menu.
contactUs.hoverHM();
screenshot = ((TakesScreenshot) PageFactoryBase.getSharedWebDriver()).getScreenshotAs(OutputType.BYTES);
scenario.embed(screenshot, "image/png");
This did the trick for me. I am pretty sure it will work for you.
_driver = new FirefoxDriver();
_driver.Navigate().GoToUrl("http://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_event_mouseover_mouseout");
_driver.SwitchTo().Frame(_driver.FindElement(By.Id("iframeResult")));
Actions builder = new Actions(_driver);
builder.MoveToElement(_driver.FindElement(By.TagName("p"))).Build().Perform();
var screenshot = ((ITakesScreenshot)_driver).GetScreenshot();
var filename = new StringBuilder("D:\\");
filename.Append(DateTime.Now.ToString("HH_mm_ss dd-MM-yyyy" + " "));
filename.Append("test");
filename.Append(".png");
screenshot.SaveAsFile(filename.ToString(), System.Drawing.Imaging.ImageFormat.Png);
After hovering mouse on the text, it turns yellow and below is the screen shot that I took.
Below is another approach where you can use 'Print screen' Key in your Test code and get the image from the clipboard in the system.
What is have done is used KeyEvent 'PRTSC' to get the Image into the system clipboard and then get the system clipboard to write it to a file. I hope it will also copy the mouseover.
Robot rob = new Robot();
rob.keyPress(KeyEvent.VK_PRINTSCREEN);
Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable content = clip.getContents(null);
BufferedImage img = (BufferedImage)content.getTransferData(DataFlavor.imageFlavor);
ImageIO.write(img, "png", new File("D:\\test.png"));
I have tried the same scenario but for clickAndHold for hover skin. It worked for me with the help of Actions as below:
WebElement elm = driver.findElement(By.id("btn1"));
Actions builder = new Actions(driver);
Action act = builder.clickAndHold(elm).build();
act.perform();
try {
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File("c:\\Img\\screenshot.png"));
} catch (IOException e) {
e.printStackTrace();
}
act = builder.release(elm).build();
act.perform();
You can instead replace clickAndHold with moveToElement Mouse hover the element. take the screenshot then release the element or move away from it.
Thanks everyone for answering on this thread.
I am able to take screenshot using robot as suggested by Vivek.
builder.moveToElement(getSharedWebDriver().findElement(By.xpath("//div[#class='brand section']/ul/li[#class='active hasflyout']"))).perform();
Robot robot = new Robot();
Point point;
point = getSharedWebDriver().findElement(By.xpath("//div[#class='brand section']/ul/li[#class='active hasflyout']")).getLocation();
int x = point.getX();
int y = point.getY();
robot.mouseMove(x,y);
In ideal case, either perform() or mouseMove() should be used. But somehow in my case, i had to use both the functions.

Selenium webdriver: Unable to send keys In a new popup window

Using selenium web-driver I am trying to put region name In the text box In new popup screen and click on save button. I using the below script for that
String mainWindowHandle1=driver.getWindowHandle();
driver.switchTo().window(mainWindowHandle1 );
driver.findElement(By.id("MainContent_imgAddRegion")).click();
Thread.sleep(5000);
java.util.Set<String> s1 = driver.getWindowHandles();
Iterator<String> ite1 = s1.iterator();
while(ite1.hasNext())
{
String popupHandle=ite1.next().toString();
if(!popupHandle.contains(mainWindowHandle1))
{
driver.switchTo().window(popupHandle).findElement(By.id("txtRegionName")).sendKeys("South Region");
Thread.sleep(3000);
driver.findElement(By.id("txtRegionName")).sendKeys("South Region");
Thread.sleep(1000);
driver.findElement(By.id("btnSave")).click();
By doing this I am able to open the new popup screen to enter the region but, I am unable to send keys [region name] and save the text.Even I am not getting any failed report when I run the test.
This may be due to iFrames presence.
Look in the HTML code and check if the text field that you are trying to send keys to and the save button are included in some sort of iFrame.
If so, you will need to do something like:
driver.switchTo().defaultContent();
driver.switchTo().frame("framename");
driver.findElement(By.id("txtRegionName")).sendKeys("South Region");
driver.findElement(By.id("btnSave")).click();
Hope it helps!

Could not switch between browsers in selenium webdriver

Iam trying to switch between browser ie on click of a button it launches a new browser it
is finding the handle ..the problem is it is not able to find the object inside the new browser searched with id,xpath,name etc can some one give me any suggestion on the same.
also it is able to match the url as well.
please provide me the solution on the same.
below is the code.
//Previous screen
Set windows = driver1.getWindowHandles();
driver1.findElement(By.id("findButton")).click();
//switching handle for the new screen
driver1.switchTo().window("Customer Search");
driver1.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
int i = 1;
while(i<= 10){
for (String handle : driver1.getWindowHandles()) {
String myTitle = driver1.switchTo().window(handle).getTitle();
System.out.println("myTitle value : " +myTitle);
//customer search is the new window title
if(myTitle.equalsIgnoreCase("Customer Search")){
driver1.manage().window().maximize();
//if i pass the right url of the screen that is also matching here i have given dummy("sshsj")
if(driver1.getCurrentUrl().equalsIgnoreCase("sshsj"));
{
System.out.println("Url is matching");
//But not able the recognise the object on the new window.
driver1.findElement(By.xpath("html/body/left/form/table/tbody/tr[2]/td[1]/input")).sendKeys("kamal");
}
You can use JS to open a new window, it's faster.
IJavaScriptExecutor jscript = driver as IJavaScriptExecutor;
jscript.ExecuteScript("window.open()");
Then to switch windows, use the window handles:
List<string> handles = driver.WindowHandles.ToList<string>();
driver.SwitchTo().Window(handles.Last());
driver.get(url);
driver.findElement(By.xpath("html/body/left/form/table/tbody/tr[2]/td[1]/input")).sendKeys("kamal");
It is possible that the element may be present inside an iframe. In that case, you need to switch to that iframe before you can access any element inside the iframe.

Resources