Selenium actions multithreading - java

I would like to open multiple Selenium WebDrivers and process them in different threads. The question is how do Selenium Action class share keyboard/ mouse resources?
public class InterruptInput implements Runnable {
public static void main(String[] args) {
// two instances of action will run simultaneously
new Thread(new InterruptInput()).start();
new Thread(new InterruptInput()).start();
}
#Override
public void run() {
// not sure if the same can be replicated using ChromeDriver
WebDriver driver = new FirefoxDriver();
Actions act1 = new Actions(driver);
act1.moveToElement(searchBar)
.click()
.sendKeys("G")
.pause(1000)
.sendKeys("O")
.pause(1000)
.sendKeys("O")
.pause(1000)
.sendKeys("G")
.pause(1000)
.sendKeys("L")
.pause(1000)
.sendKeys("E")
.pause(1000)
.perform();
}
}
The observed result is:
Two browsers will open. Each will type GOOGLE to the search bar in 7 seconds. There are no interference.
If I manually click somewhere on the same page, and move the search bar out of focus, the input will be interrupted.
If I manually open a new tab in one of the browsers, or switch to other apps in the operating system, GOOGLE will finish typing in the background.
How is this achieved? Does this mean I can open as many instances of WebDriver, and not worry about clogging up I/O. How is this different from Java's Robot class, which actively takes over keyboard and mouse control? For the reference, I am using Windows 10. Not sure if this is platform dependent.
The fundamental purpose being, I am writing a simple app that allows the user (me) to scrape some websites, while obviously allowing the user to do other work on the computer.

When you use Actions class you do not use real input devices. The only thing you share is what you have in your code - a WebDriver object that is new for each of your threads so that there is no interference.
So by performing a "mouse move" you send a command to webdriver that sends the event to a browser that it would receive if you would use the real mouse or keyboard. The real mouse pointer would not move.

Related

Alternate ways to handle Robot Class Steps in Selenium Test

My application supports only IE currently. In one case, it opens a pop up window with some fields which are not inspect-able. I am using Robot class features (tab sequences, mouse clicks, sendkeys) to enter data, do a search and other steps on that.
This scenarios works fine in my local but due to large volume of my scenarios we are running them in bulk on cloud machines where the Robot keys functions are not supporting.
Is there any alternate ways to handle this case to continue my scenarios running on virtual machines.
Have anyone faced such cases & can you share your experience handling it in selenium script
Robot class was the option tried which is working in local, need solution to run them on virtual machines.
Tried Switch to pop up window, frame - those are not working as well, the pop window is not getting identified itself (In the window its displayed as Search -- WebPage Dialog)
Below is a sample code snippet - i am using for a search function in the pop up using Robot Class
try {
Thread.sleep(5000);
sendTab(34);
sendRobotKey("enter");
String name ="ABC";
copyToClipboard(name);
Thread.sleep(2000);
cntrolVRobotKey();
Thread.sleep(2000);
sendRobotKey("enter");
Thread.sleep(2000);
sendTab(4);
Thread.sleep(2000);
sendTab(1);
sendRobotKey("enter");
}
catch (Exception e) {
e.printStackTrace();
}
}
Use AutoIt instead of robot class

Is there any way to record the screenshots of minimized browser windows

I am using Java and selenium to write some tests. I need to have my screen records while the tests are running it makes much easier for me to track if any bugs occurs. The problem is that I need to run more than one tests at the same time and as I have only one monitor I cannot record all of their screen records at the same time so I have to run the test one after each other. I was wondering if there is any way that I can run all my tests and actually minimize their browsers windows but still record what is going on at each minimized chrome window. My question may sound a bit very strange but that makes my testing very faster.
Yes, definitely we can take multiple screenshots. There is no affect whether the browser is in minimize or Maximize condition. Just you have to switch the new opened window & add "Take screenshot" method after each method where you have to take screenshot.
Take screenshot method can work in both mode while browser is either in Minimize or Maximize condition.
For screenshot you can may use the below code:
public void getscreenshot() throws Exception
{
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
//The below method will save the screen shot in d drive with name "screenshot.png"
FileUtils.copyFile(scrFile, new File("D:\\screenshot.png"));
}
or you can opt for the multi-screen capture and the code for that is below :
public void GoogleAbout() throws Exception {
driver.get(baseUrl); // Enter the URL as per your choice
driver.findElement(By.linkText(Prop.getProperty("AboutLinkText"))).click(); //find the web element
MultiScreenShot multiScreens = new MultiScreenShot("C:\\New\\","GoogleAbout"); // Here we need to create the object which will take two arguement one is the path to save the file and second one is class name
multiScreens.multiScreenShot(driver);
driver.findElement(By.linkText("More about our philosophy")).click();
multiScreens.multiScreenShot(driver);
}
To enable the multi-screenshot you have to download the JAR file and then attached it to your project and then :
import multiScreenShot.MultiScreenShot;

Selenium Chrome Driver send key press combinations to window

I need to perform a key press combination on Selenium Chrome driver.
The action is not sending test to text box or clicking on a button.
I am actually not interested in sending keys to any specific web element.
For example, I would like to perform command+R (reload on Mac OS).
(Reloading is just an example for the explanation, not my ultimate goal)
My code is the following:
public static void keyPressCombnaiton() {
Actions action = new Actions(browser);
action.keyDown(Keys.COMMAND)
.sendKeys("r")
.keyUp(Keys.COMMAND)
.build()
.perform();
}
I have spend hours searching and trying only got no luck.
Any help is appreciated!
The WebDriver spec is element-focussed, and doesn't define any method to send keys to the window, the screen, to browser chrome - only to elements.
Use of the Selenium Actions class for Cmd-R works on my Mac in Firefox (45), but only when run in the foreground - and seemingly not at all in Chrome. Presumably this is down to differences in the implementations of the remote Keyboard implementation, which it's probably best not to rely upon.
The most efficient way and non-platform-specific way to request a page reload is using JavaScript:
((JavascriptExecutor) driver).executeScript("document.location.reload(true)");
However, JavaScript doesn't let you "just send keys".
The only other way is via the Java AWT Robot class:
Robot robot = new java.awt.Robot();
robot.keyPress(KeyEvent.VK_META); // See: http://stackoverflow.com/a/15419192/954442
robot.keyPress(KeyEvent.VK_R);
robot.keyRelease(KeyEvent.VK_R);
robot.keyRelease(KeyEvent.VK_META);
This "blindly" sends key combinations to whichever windows / components are on screen at the time, so if your browser window has been hidden or minimised, this will not work.

How to simulate mouse movement in selenium using java

I have a requirement that when a certain automation script is run, the browser should show the cursor moving from one field to another as the script moves ahead. I am not sure about what exactly I need to do to get it done. I used the Action class to implement it but it's not working.
Please find the code I have implemented below:
public void MouseHover(WebElement Mouse,WebDriver driver) throws InterruptedException
{
Actions act = new Actions(driver);
act.moveToElement(Mouse).build().perform();
System.out.println("Curser movement Performed Successfully");
}
The java.awt.Robot class can be used to programmatically move the user's mouse (among other things). See: Link.
For example:
Robot r = new Robot();//construct a Robot object for default screen
r.mouseMove(1360, 7);//move mouse to java coords 1360, 7
r.mousePress(InputEvent.BUTTON1_MASK);//press the left mouse button
r.mouseRelease(InputEvent.BUTTON1_MASK);//release the mouse button

Webdriver showModalDialog

We are using webdriver for our functional tests. But our application uses the showModalDialog JS function a lot to open a popup. When we try to test this functionality with webdriver it hangs from the moment the popup is opened.
We tried several things to test this:
Using the workaround explained here. But this seems to be a fix for selenium and not for webdriver. We tried it but it didn't work.
Searching for a good alternative, HtmlUnit opened the modal dialog and could interact with it, but it has it's drawbacks like no visual help to fix certain tests and it stopped execution when it detected a JS error in a JS library we have to use but have no control over.
How can we test this or work around this problem?
From my experiences with various automation tools interaction with "webpage dialog" windows opened from IE using window.showModalDialog() or window.showModelessDialog() is not available.
Since the window is not a "true" window (look at the taskbar, it doesn't even show up) most tools can't "inspect" it and/or interact with it.
However if you do find a tool that will, please advise - there are many people looking for such a beast.
That all said, if you can possibly avoid using either of these 2 proprietary methods you'll have much more luck.
(and yes, for the picky ones, Firefox and Chrome have adopted these kind of dialogs but they don't work quite the same)
None of the answers answer the question. If the driver hangs, then you can't call any methods on it. The question is NOT about finding the pop up, it is about how to stop the driver hanging. The only way I have found is to not use showModalDialog. This can be done by adding the folowing to your test code :
((JavascriptExecutor) driver).executeScript("window.showModalDialog = window.open;");
which calls window.open each time your JavaScript calls window.showModalDialog.
I am using webdriver.SwitchTo().Window() method but my concern is my popup window does not have "Name"
When I use webdriver.WindowHandles it return only one handle, I am using this statement after popup window open.
As I don't have name / handle I cannot switch from parent window to child window.
Any other solution to do the same functionality
First we have to switch to the active element:
driver.switchTo().activeElement();
To check whether we have actually switched to the correct active element:
driver.switchTo().activeElement().getText();
Even if the window doesn't have name u can use
driver.switchTo.defaultcontent();
and perform the operation you want to execute
or else you can get the window handle name using the below command
for (String handle : driver.getWindowHandles()) {
driver.switchTo().window(handle); }
hope this should work for you.
Issue 284 is for WebDriver. It seems that it will be implemented only after Issue 27 will be implemented, so the fix should be in Beta 1 or 2 of WebDriver.
Set<String> beforePopup = driver.getWindowHandles();
Set<String> afterPopup = driver.getWindowHandles();
afterPopup.removeAll(beforePopup);
if(afterPopup.size()==1){
System.out.println(afterPopup.toArray()[0]);
}
driver.switchTo().window((String) afterPopup.toArray()[0]);
What I have been using and it works great for us on with IE and Firefox is to go through popups
and look for a a unique text on the popup you are trying to interact with. Here is the method, let me know if it works for you. Please note the line driver = driver.switchTo().window(windowHandle);
public void switchWindow(String containingText, WebDriver driver) throws Exception {
if ( StringUtils.isEmpty(containingText))
return;
int counter = 1;
int numOfpopups = driver.getWindowHandles().size();
System.out.println("Waiting for popup to load..... # handles:" + numOfpopups);
while ( numOfpopups < 2 && ((counter%10) != 0) ) {
counter++;
try{Thread.sleep(1000);}catch (Exception e) {}
}
System.out.println("Done waiting for..... " + counter + " seconds");
if (driver.getWindowHandles().size() < 2)
throw new BrowserException("Timeout after " + counter + " secs. No popup present. ");
System.out.println("Going through window handles...");
for (String windowHandle : driver.getWindowHandles()) {
driver = driver.switchTo().window(windowHandle);
if ( driver.getPageSource().contains(containingText)
return;
else
continue;
}
throw new Exception("Window containing text '" + containingText + "' not found");
}
To my knowledge, webdriver has no built-in functionality to handle modal windows as of now. Webdriver will hang once you click button which opens modal window. This happens due to JS on parent window halts until child window is closed.
To handle modal windows such as this one, see below for possible workaround written in Java. The main idea is to perform action that opens modal window (click on the button) in new thread.
/**
* Click button to open modal window and switch to it
* #param we webElement handle of a button
*/
public void clickToOpenModal(final WebElement we) {
//Get handles of all opened windows before opening modal window
Set<String> initWindowHandles = getDriverInstance().getWindowHandles();
//Create new thread and click button to open window
Thread thread1 = new Thread() {
#Override
public void run() {
//Click button
click(we);
}
};
thread1.start();
//Wait for window to appear
waitForWindow(initWindowHandles, pauseL);
thread1.interrupt();
thread1 = null;
//Get handles of all opened windows after opening modal window
Iterator<String> it = getDriverInstance().getWindowHandles().iterator();
//Select handle of modal window
String windowHandle = "";
while(it.hasNext()){
windowHandle = it.next();
}
//Switch focus and work on the modal window
getDriverInstance().switchTo().window(windowHandle);
}
The solution by Hugh Foster works, i tried this and succeeded
((JavascriptExecutor) driver).executeScript("window.showModalDialog = window.open;");
You can find the url of modal dialog then open it on another tab, it will work as normal.
In case you want to deal with open modal dialog, you can try to send "tab" key for move around objects and "send keys... enter" for setText or click.
Note: Below is some information why you cannot use selenium webdriver for work with that modal.
Modal pop-up - This is very specific to IE, Microsoft defined it as
When Windows Internet Explorer opens a window from a modal or modeless HTML dialog box by using the showModalDialog method or by using the showModelessDialog method, Internet Explorer uses Component Object Model (COM) to create a new instance of the window. Typically, the window is opened by using the first instance of an existing Internet Explorer process. When Internet Explorer opens the window in a new process, all the memory cookies are no longer available, including the session ID. This process is different from the process that Internet Explorer uses to open a new window by using the open method.
http://msdn.microsoft.com/en-us/library/ms536759(VS.85).aspx
MSDN blog on Modal dialog
When user select Model popup, parent window is blocked waiting for the return value from the popup window. You will be not able to see the view source of the page, need to close the popup then only the parent window is activated.

Categories

Resources