Selenium: switch tab in RemoteWebDriver with C# - c#

Currently, I'm trying to run my Selenium tests on Safari using Selenium Grid and RemoteWebDriver. This is my setup:
Mac OS Sierra 10.12.6 as a machine for running tests.
Selenium server 3.5.3.
Safari 11.
C# Selenium WebDriver and Selenium Support (latest version).
I'm using port forwarding on my host OS (Windows 10) to forward requests to Mac, running on my Virtual Machine. On my Mac I have Selenium Grid hub, which I run like this:
java -jar selenium-server-standalone-3.5.3.jar -role hub -port 4723
Also, there is a node:
java -jar selenium-server-standalone-3.5.3.jar -role node -hub http://10.0.2.15:4723/grid/register
In code, I start my driver like this:
SafariOprions options = new SafariOptions();
IWebDriver driver = new RemoteWebDriver(new Uri(hubURL), options.ToCapabilities());
My tests are running fine with current setup. But when it comes to clicking a link with attribute target='_blank' I'm starting to face some troubles. For other drivers, which I run locally, I can switch tab without any trouble: I'm getting driver.WindowHandles before I click a link, then I click a link and again retrieve Window Handles to compare with previous handles. After that I use driver.SwitchTo().Window(newHandle) and everything is ok.
But when it comes to RemoteWebDriver (or SafariDriver from Apple, I cannot say more precisely) I'm always getting only one Window Handle, even if the new tab is opened and i can see it.
I'm trying to avoid switching tab with "Command + T" as one of solutions suggested, because my tests are meant to be run on all browsers (Chrome, Firefox, Opera, Edge, Safari) and this wont work.
UPDATE: I've tried running Chrome and other browsers in Selenium Grid via RemoteWebDriver and I can say that this is not an issue of RemoteWebDriver. Next, I've installed Visual Studio for Mac and rewrite several things to run my tests without Selenium Grid, just using this code:
//if memory serves, just like this
SafariOptions options = new SafariOptions();
SafariDriver driver = new SafariDriver(options);
But, unfortunately, this didn't help. Driver navigated me to the page, clicked the link and opened a new tab, but without any switch. When I checked for driver.WindowHandles I've only got one, although there was two visible tabs. Neither driver.SwitchTo().ActiveElement nor driver.SwitchTo().Frame(hardcoded_frame_name) doesn't seem to work. Pretty long waits (for 60 seconds after opening the link and another one after that) aren't working too. Now I think that this is really a bug and I will try to report this to Apple as soon as I can.
But for now, maybe someone has a fancy workaround for this?

As we discussed in the comments, it seems to be a timing issue. So we will induce
WebDriverWait to sync up with the trailing Browser instance. I am providing a code block as a solution through Selenium-Java, consider implementing it in C# and update me if it works for you.
driver.get("http://www.google.com");
System.out.println("Page Title is : "+driver.getTitle());
String parent_window = driver.getWindowHandle();
((JavascriptExecutor) driver).executeScript("window.open('http://facebook.com/');");
WebDriverWait wait = new WebDriverWait(driver,3);
wait.until(ExpectedConditions.numberOfWindowsToBe(2));
Set<String> allWindows_1 = driver.getWindowHandles();
ArrayList<String> tabs = new ArrayList<>(allWindows_1);
driver.switchTo().window(tabs.get(1));
wait.until(ExpectedConditions.titleContains("Facebook"));
System.out.println("First Child Handle : "+driver.getTitle());

I could help you with the Java version:
After the actions done, do this below.
//Store the parent window
String parentWindow = driver.getWindowHandle();
//Open a new Windows(Mailtrap)
String a = "window.open('https://mailtrap.io/signin','_blank');";
((JavascriptExecutor)driver).executeScript(a);
//This Thread.sleep is useful with Safari. Do not remove.
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Take control over new browser
for(String handle: driver.getWindowHandles()){
driver.switchTo().window(handle);
}

Related

Is there a way to activate IE mode in Edge Options?

Hello,
I want to achieve this by having an option inside the EdgeDriver but I cant seem to find it anywhere on the map?
I am trying to open a page in IE mode inside Edge with Selenium and EdgeDriver.
Is there a way to achieve this great thing? [pun intented]
I can see 2 questions in this thread.
Is there a way to activate IE mode in Edge Options?
There is no way to activate IE mode bypassing the Edge options parameter in the Selenium Edge driver.
I am trying to open a page in IE mode inside Edge with Selenium and EdgeDriver. Is there a way to achieve this great thing?
Yes, it is possible to automate the IE mode in the new MS Edge browser using the Selenium web driver.
The new Microsoft Edge allows you to run IE11 validation for legacy sites in addition to your modern experiences. To run your IE11 tests in Microsoft Edge, download the IEDriverServer from Selenium. Then you must pass in a capability to put Microsoft Edge into IE Mode and then run your tests.
Because this capability puts the whole browser into IE11 Mode, you cannot simultaneously test content that should render in the modern Chromium engine, but you should be able to run all of your IE11 tests and validate the rendering in Microsoft Edge. Note that this code requires an update to IEDriverServer which should be included in the next release of Selenium.
After you download the new IEDriverServer from SeleniumHQ and follow the directions for the “Required Configuration” as documented here, you can run the following code to launch the new Microsoft Edge in IE11 mode and run some tests:
static void Main(string[] args)
{
var dir = "{FULL_PATH_TO_IEDRIVERSERVER}";
var driver = "IEDriverServer.exe";
if (!Directory.Exists(dir) || !File.Exists(Path.Combine(dir, driver)))
{
Console.WriteLine("Failed to find {0} in {1} folder.", dir, driver);
return;
}
var ieService = InternetExplorerDriverService.CreateDefaultService(dir, driver);
var ieOptions = new InternetExplorerOptions{};
ieOptions.AddAdditionalCapability("ie.edgechromium", true);
ieOptions.AddAdditionalCapability("ie.edgepath", #"\\msedge.exe");
var webdriver = new InternetExplorerDriver(ieService, ieOptions, TimeSpan.FromSeconds(30));
webdriver.Url = "http://www.example.com";
}
Output:
Notes:
Make sure you are using the latest version of the IE driver server.
I suggest making a test with the latest version of the Stable Edge browser.
Try to pass the full path of the Edge browser in the 'ie.edgepath' capability. For example:
ieOptions.AddAdditionalCapability("ie.edgepath", #"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe");
Make sure you close all the already opened instances and tabs of the Edge browser before running the code. Otherwise, it will generate an error.
References:
Scroll to the Automating Internet Explorer mode point in this link.
kypflug/webdriver-edge-ie-mode.cs
Below code (which is in VB.NET, but you can easily modify it to C#) will start Chromium Edge in IE Mode
Dim ieService = InternetExplorerDriverService.CreateDefaultService("DIRECTORY_PATH_HAVING_IEDriverServer.exe", "IEDriverServer.exe")
Dim ieOptions = New InternetExplorerOptions
ieOptions.IgnoreZoomLevel = True
ieOptions.AddAdditionalCapability("ie.edgechromium", True)
ieOptions.AddAdditionalCapability("ie.edgepath", "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe")
Dim driver = New InternetExplorerDriver(ieService, ieOptions, TimeSpan.FromSeconds(60))
driver.Navigate().GoToUrl("https://example.com")
You can download IEDriverServer from https://www.selenium.dev/downloads/

Selenium tests open IE in background on TFS build server

we are trying to use Selenium for testing our MVC application. On localhost in VS2017 , it´s running correct, the tests open IE, run the test and then close the IE.
On TFS build server, the tests start IE somehow on background (in Task manager I see two iexplorer.exe processes), but the window of IE is not visible. The tests find elements, but they are not able to write text in textbox, always get error like "Element cannot be interacted with via the keyboard because it is not focusable"
Localy I run Win10 and IE11, TFS build server run Windows Server 2012 R2 and IE11 .
//initialize driver in test constructor
InternetExplorerOptions options = new InternetExplorerOptions();
options.IntroduceInstabilityByIgnoringProtectedModeSettings = true;
options.RequireWindowFocus = true;
driver = new InternetExplorerDriver(options);
driver.Manage().Window.Maximize();
//test itself
driver.Navigate().GoToUrl(appURL);
var x = driver.FindElement(By.Id("FiltrADuvodDotazu_DuvodDotazu"));
x.SendKeys("Automatizovaný test"); //here I get error
Is there way to run IE visibly, so the tests can interact with it?
I guess your agent run as a service and this is the reason the tests run on "headless mode" (and IE not supports it, like mentioned in the comments).
To solve it you need to configure the agent as an interactive process with auto-logon enabled.
When configuring the agent, select 'No' when prompted to run as a service. subsequent steps then allow you to configure the agent with auto-logon.
More info you can find here.

Seleniums Gecko driver crashes when going to new web pages

I am using the new Gecko Driver to test in Firefox. When I change the url it often fails. I have a test that goes to 10 different pages to perform a very basic health check. The pages always load when using Firefox manually (not Gecko/Selenium), but when using the Gecko driver it fails on the GoToUrl().
It's not consistent which of the ten pages it fails on, but it is always consistently failing on one of the ten. When it fails Firefox closes and an error message pops up asking if I want to submit the details to Mozilla.
Am I doing something wrong, or is there some restriction with the Gecko driver that I am unaware of? The Chrome and internet explorer drivers handle the exact same test just fine.
var service = FirefoxDriverService.CreateDefaultService(DriverPathOnSystem);
var driver = new FirefoxDriver(service);
driver.Navigate().GoToUrl(url);
EDIT
Selenium.Support v3.4.0 (nuget)
Selenium.WebDriver v3.4.0 (nuget)
Firefox 51.0.1 (32-bit) but also using the most recent version on the
build machine and it has the same failure there
Gecko 0.16.0
Upon further research I discovered I was actually using WebDriver v3.2.0.
I updated WebDriver to v3.4.0,
updated FireFox to 53.0.0,
updated GeckoDriver to 0.16.1
cleaned the solution and rebuilt and it worked.

C# Based Testing Automation Attaching to Existing Browser

C#, Visual Studio 2015, .NET 4.x Framework, Internet Explorer 11 (or latest Chrome), Windows 8.1 Pro workstation.
For testing purposes, using a Windows Forms or Console application written in C#, I need to automate an existing browser instance running on a Windows 8 or 10 system.
I created a Windows Forms application, and I'm able to automate a browser that I start using the Navigate(...) method within the application using the WebBrowser control and do things like click on a button in a Javascript popup, login using a username and password, select an item from the datagridview and click on the "edit" button associated with that item.
However, once that "edit" button is clicked, additional browser windows are created that are now running outside the "scope" of the WebBrowser control.
The web application opens new instances of the browser using window.open(...,_blank);
I've tried working with the NewWindow event, but I don't seem to be able to grab any kind of "handle" or such to the newly opened windows. The event fires, but what I'm seeing when I debug inside the event is just information about the window that I'm currently working with (not the newly spawned window).
The other things I've tried are Selenium and WatIn.
For both, the examples I had an instance of Internet Explorer 11 running on my Windows 8.1 Pro workstation at www.google.com.
Generally, the examples seem to show that for "attaching to an existing instance" of a browser the examples first firing off the browser. I've tried to connect to an existing browser using both libraries, and I've not had success.
I've tried to use the RemoteWebDriver(...) for Selenium, using the InternetExplorer driver. Another Stack Overflow post indicates I don't need the server component running because the browser and application for testing are on the same machine. My code is as follows:
private void doSeleniumStuff()
{
DesiredCapabilities desired = DesiredCapabilities.InternetExplorer();
using (IWebDriver driver = new RemoteWebDriver(new Uri("http://www.google.com/wd/hub"), desired))
{
IWebElement query = driver.FindElement(By.Name("q"));
query.SendKeys("Cheese");
query.Submit();
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(d => d.Title.StartsWith("cheese", StringComparison.OrdinalIgnoreCase));
Console.WriteLine("Page title is: " + driver.Title);
}
}
I'm somewhat confused about the URL used in the RemoteWebDriver constructor. The documentation doesn't seem to describe this usage well. What is this "/wd/hub" usage all about?
It failes with:
{"Unexpected error. <!DOCTYPE html>\r\n<html lang=en>\r\n <meta charset=utf-8>\r\n <meta name=viewport content=\"initial-scale=1, minimum-scale=1, width=device-width\">\r\n <title>Error 404 (Not Found)!!1</title>\r\n <style>\r\n *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}#media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}#media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}#media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}\r\n </style>\r\n <a href=//www.google.com/><span id=logo aria-label=Google></span></a>\r\n <p><b>404.</b> <ins>That’s an error.</ins>\r\n <p>The requested URL <code>/wd/hub/session</code> was not found on this server. <ins>That’s all we know.</ins>\r\n"}
I've tried using the AttachTo(...) method in WatIn.
[STAThread]
private void doWatNStuff()
{
using (IE myIE = Browser.AttachTo<IE>(Find.Any))
{
DomContainer dc = myIE.DomContainer;
}
}
Fails in the using with
{"Could not find an IE window matching constraint: Any. Search expired
after '30' seconds."}
The example code provided for WatIn has the code first creating an instance of IE and then attaching to it. I can't help but think that WatIn can attach to a running instance of a browser, but WatIn must first create that instance.
That won't meet my needs.
My final attempt was to use System.Windows.Automation to get an open Internet Explorer window and try to work with it. While I get the window, all I can get access to are the Windows and Transform patterns. Hence, I could potentially automate the resizing of the browser window and close it. But, I can't get the DOM or anything useful.
There are a few articles out there about using Interop with MSHTML or SHDocVw, but nothing super helpful.
I would appreciate any guidance anyone can provide on using whatever tools possible for a .NET C# Windows Forms or Console application to use to somehow connect to an independently opened browser window on the same Windows machine and automating it.
I've been using WatiN succesfully for this. A console app with Program.cs that looks like the following works for me:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using WatiN.Core;
namespace WatinTest
{
class Program
{
[STAThread]
static void Main(string[] args)
{
var ie = IE.AttachTo<IE>(Find.ByTitle(new Regex(".*")));
foreach (var div in ie.Divs)
{
Console.WriteLine(div.IdOrName);
}
Console.ReadLine();
}
}
}
This is with Windows 10 and WatiN 2.1.0.

cross browser testing using codedui?

i have issue in cross browser testing using codedui.
Using below code,
Process.Start("firefox", url);
BrowserWindow.CurrentBrowser = "firefox";
Browser = BrowserWindow.Launch(new System.Uri(url));
Keyboard.SendKeys("^{0}");
all code developed in IE . but now i have to execute code in firefox or chrome.I am going to execute the code in forefox.I am using this code here
Browser = BrowserWindow.Launch(new System.Uri(url));
in this line getting error like "An error occurred while connecting to Firefox".how to resolve this issue?I installed selenium components also. if i remove this line I am getting diffrent error like " Unable to find browser"...Please help.
Out of the box Visual Studio doesn't support cross browser CodedUI testing.
You're going to need to install Selenium components to allow for cross browser testing in Visual Studio.
Details on that can be found here:
http://blogs.msdn.com/b/visualstudioalm/archive/2012/10/30/introducing-cross-browser-testing-with-coded-ui-tests.aspx
Selenium components can be found here:
http://visualstudiogallery.msdn.microsoft.com/11cfc881-f8c9-4f96-b303-a2780156628d
Looks like CodedUI doesn't support playback on very many different browsers http://msdn.microsoft.com/en-us/library/dd380742(VS.100).aspx
There are some other tools out there http://watin.org/ is one, but I can't find anything myself that will really solve your problem.
Try
BrowserWindow.CurrentBrowser = "firefox";
BrowserWindow WebApp;
WebApp.CopyFrom(BrowserWindow.LaunchUrl(new System.Uri(url)));
I set up something similar to the following and it works well (I hand code everything, bypassing the UIMap).
public class WebApp : BrowserWindow
{
private string _url;
public WebApp(string url)
{
//define search properties using this keyword so the web application can be treated as a browser
_url = url;
BrowserWindow.CurrentBrowser = "Chrome";
this.CopyFrom(BrowserWindow.Launch(new Uri(url));
}
}
You can overload the constructor, of course, by adding a parameter for the browser to use or whether to start up the browser or not.
By setting up the web application as a BrowserWindow, you can have one open and ready and the playback engine should find it. I find this helps when working on tests (in IE).
Just a reminder, you do need the Selenium plug-in and that plug-in will only work for playback, not recording.
Cheers!
In our environment, we set up the Launch() method by doing the following:
public void LaunchBrowser(string uri)
{
BrowserWindow.CurrentBrowser = "firefox";
BrowserWindow myBrowser = BrowserWindow.Launch(new System.Uri(uri));
}
One thing to note is that if there is a firefox process already running in the background, the WebDriver will not launch a new instance, so be sure that all instances of firefox are shut down before the LaunchBrowser() is called. I've found that there are Java plugins that can keep it running in the background, so try to disable those that you don't need. Another good place to look, if you check your Task Manager and this is the case, is here.

Categories