Unable to identify PageObjects when calling second time - selenium-webdriver

Below is the page object framework we are using in automating our GUI test cases using selenium.
Here is the scenario I need to do in GUI .
1. Login to home page
2. Click on a link to open the query page
3. Enter value in text box and click on Query button
4. Close this page
5. Again click on link to open query page
6. Enter value in text box and click on query button
7. Close this page
Here I created PageObjects for Text box and Query button.
A reusable action is created to open the page by clicking on link and enter the value in text box and click on query and close the page.
My issue is that when I call the reusable action first time , its all working fine. When I call the reusable action second time it is not identifying the text box or query button.
Why is it so?
My testcase looks like this.
Testcase :
public class TC_01 extends BaseClass{
LoginApp login=new LoginApp();
GUIPageActions spa = new GUIPageActions();
login.loginTest();
spa.queryByTN(firstTN,"xyz"); // It is all working fine
spa.queryByTN(TN,"abc"); // Here pageObjects are not identified.
}
Reusable actions:
GUIPageActions.java File
GUIQueryPage soaSubP=new GUIQueryPage (driver);
public void queryByTN(String TN,String status) throws InterruptedException{
//opening page
soaSubP.setTN(TN);
soaSubP.clickQuery();
driver.close();
//closing that page.
}
PageObjects:
GUIQueryPage.java
// PageObjects are created for edit box and Query button
#FindBy(id="fromTn")
#CacheLookup
WebElement fromTn;
#FindBy(id="queryButton")
#CacheLookup
WebElement QueryButton;
public void setTN(String TN){
fromTn.clear();
fromTn.sendKeys(TN);
}
public void clickQuery(){
wait.until(presenceOfElementLocated(By.id("queryButton")));
QueryButton.click();
}

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

How can I click a web element for a 3rd party page?

I have an Ecommerce website and on one page there is a button named Place Order. When I click on the Place Order button, then it allows me to open a new window named Paypal. I need to stay on the same tab without opening the new window. After that I need to click on the element for that Paypal page.
How can I do this?
My code is as follows:
String parent_handle= driver.getWindowHandle();
System.out.println(parent_handle);
driver.findElement(By.xpath(".//*[#id='co-place-order-area']/div[2]/div[3]/div/button")).click();
new WebDriverWait(driver,10).until(ExpectedConditions.numberOfWindowsToBe(1));
Set<String> handles = driver.getWindowHandles();
System.out.println(handles);
for(String handle1:handles)
if(!parent_handle.equals(handle1))
{
driver.switchTo().window(handle1);
System.out.println(handle1);
}
I don't know about java but in C# you would use PopupWindowFinder class
var target = driver.findElement(By.xpath(".//*[#id='co-place-order-area']/div[2]/div[3]/div/button"));
PopupWindowFinder finder = new PopupWindowFinder(driver);
var parent = driver.CurrentWindowHandle;
string newHandle = finder.Click(target);
driver.SwitchTo().Window(newHandle);
Then after you deal with the new window you can switch back to the parent window.

Confluence Create Button

I'm creating a new Page in Confluence with Selenium.
However after clicking create, I'm unable to click the send create button.
driver.findElement(By.id("create-page-button")).click();
driver.findElement(By.xpath("//div[#id='create-dialog']/div/div[2]/button")).click();
driver.findElement(By.id("content_title")).sendKeys("Test Case 1");
driver.findElement(By.id("rte-button-publish")).click();
The code errors on:
Unable to locate element: {"method":"id","selector":"content_title"}
as the new page has not been created.
This is what it took to create a page for myself:
driver.findElement(By.id("create-page-button")).click();
(new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
return d.findElement(By.xpath("//*[#id='create-dialog']/div/div[2]/button")).getText().equals("Create");
}
});
driver.findElement(By.xpath("//*[#id='create-dialog']/div/div[2]/button")).click();
driver.findElement(By.xpath("//*[#id='content-title']")).sendKeys("My Test Page");
driver.findElement(By.id("rte-button-publish")).click();
I tried using the By.id for the content-title input box but it didn't work with the error being the same one as you received however doing it by xpath worked.
Also the NewDriverWait was added since the dialog box is loaded in and if you click the Create button too fast it would actually be the Next button which would result in the page not being created.

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!

Resources