I wrote this code in C# and it's not working for me.
Second url is still opening in the first tab, although I switched tabs and updated handle.
// open first page in first tab
string firstPageUrl = "http://google.com";
driver.Navigate().GoToUrl(firstPageUrl);
// getting handle to first tab
string firstTabHandle = driver.CurrentWindowHandle;
// open new tab
Actions action = new Actions(driver);
action.SendKeys(OpenQA.Selenium.Keys.Control + "t").Build().Perform();
string secondTabHandle = driver.CurrentWindowHandle;
// open second page in second tab
driver.SwitchTo().Window(secondTabHandle);
string secondPageUrl = "http://bbc.com";
driver.Navigate().GoToUrl(secondPageUrl); // FAILED, page is opened in first tab -.-
Thread.Sleep(2000); // slow down a bit to see tab change
// swtich to first tab
action.SendKeys(OpenQA.Selenium.Keys.Control + "1").Build().Perform();
driver.SwitchTo().Window(firstTabHandle);
Thread.Sleep(1000);
action.SendKeys(OpenQA.Selenium.Keys.Control + "2").Build().Perform();
I'm using latest Chrome driver.
Any ideas?
EDIT:
This is not duplicate. I am not opening links here, I want to navigate to URL I've provided. Also, I am using CurrentWindowHandle as suggested, but it is not working for me.
string secondTabHandle = driver.CurrentWindowHandle; is still returning the first tab, even if the second tab cover the first one. Try this
string firstTabHandle = driver.getWindowHandle();
Actions action = new Actions(driver);
action.SendKeys(OpenQA.Selenium.Keys.Control + "t").Build().Perform();
// switch to the new tab
for (String handle : driver.getWindowHandles()) {
if (!handle.equals(firstTabHandle))
{
driver.switchTo().window(handle);
}
}
// close the second tab and switch back to the first tab
driver.close();
driver.switchTo().window(firstTabHandle);
Not entirely sure if this is related to your problem (but I think it might be):
I've found, with selenium, that a better alternative to using Thread.Sleep() is using:
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(15));
where first argument is the selenium driver you're using, and the second argument is how long you want to wait before giving up (the timeout)
You can then call:
wait.Until(condition);
where condition is what you want to wait for. There is a selenium class that provides various useful conditions called ExpectedConditions, for example:
ExpectedConditions.ElementToBeClickable(By by)
which would wait for a particular clickable element to be ready to click.
In fact, I've found that any time the content of the page changes, it's a good idea to wait for the element you're using next like this.
Related
For practice sake, I'm writing test cases for irctc website, there I need to enter from station place and then respective stations with that code will be displayed as bootstrap dropdown and now i have to select one among them and click enter. Unfortunately there is no enter/submit button for from and to text field, please help me to continue with this test case
Here is my code
IWebElement Fromstn = driver.FindElement(By.XPath("//*[#id='divMain']/div/app-main-page/div/div/div[1]/div[1]/div[1]/app-jp-input/div/form/div[2]/div[1]/div[1]/span/i"));
Thread.Sleep(2000);
Fromstn.SendKeys("MAQ");
Fromstn.Click();
```**OR**
Actions builder = new Actions(driver); Actions hover = builder.MoveToElement(driver.FindElement(By.XPath("//*[#id='origin']"))); hover.Build().Perform(); Thread.Sleep(2000); hover.SendKeys("MAQ"); hover.Click();
from input try the below css :
p-autocomplete#origin input
To input try the below css :
p-autocomplete#destination input
Code :
driver.FindElement(By.CssSelector("p-autocomplete#origin input")).SendKeys("MAQ");
driver.FindElement(By.CssSelector("p-autocomplete#destination input")).SendKeys("some to station");
and if you wanna do Keyboard enter then probably use it with sendkeys():
something like this :
driver.FindElement(By.CssSelector("p-autocomplete#origin input")).SendKeys("MAQ" + Keys.RETURN);
See if this works:-
driver.FindElement(By.XPath("//label[text()='From']/..//input")).SendKeys("MAQ");
//Add a wait time for the drop down value to load
Actions builder = new Actions(driver);
Actions hover = builder.MoveToElement(driver.FindElement(By.XPath(".//ul[#id='pr_id_1_list']/li"))).Click().Perform();
You can try this code. For debugging see the Fromstn object in the quick watch and see if it has returned the correct element. for debugging you can also see the element is still in the form by 'inspect element' and do a find with the Xpath given when you are on the breakpoint.
IWebElement Fromstn = driver.FindElement(By.XPath("//*[#id='divMain']/div/app-main-page/div/div/div[1]/div[1]/div[1]/app-jp-input/div/form/div[2]/div[1]/div[1]/span/i"));
Thread.Sleep(2000); //you can also try by increasing the value for testing say 10 seconds
Fromstn.Clear();
Fromstn.SendKeys("MAQ");
Fromstn.Click();
I am attempting to control two browser windows via selenium using c# and a single chromedriver. The reason being that I need to share session details accross browser windows.
The code that I have tried and failed with is below;
var options = new ChromeOptions();
options.AddArguments("chrome.switches", "--disable-extensions --disable-extensions-file-access-check --disable-extensions-http-throttling --disable-infobars --enable-automation ");
options.AddUserProfilePreference("credentials_enable_service", false);
options.AddUserProfilePreference("profile.password_manager_enabled", false);
options.PageLoadStrategy = PageLoadStrategy.Default;
ChromeDriverService service = ChromeDriverService.CreateDefaultService();
service.HideCommandPromptWindow = true;
var Driver = new ChromeDriver(service, options);
//THIS WILL OPEN A NEW WINDOW. BUT BECAUSE IT IS A NEW DRIVER DOES NOT WORK FOR SHARING SESSION DETAILS.
//var TestDriver = new ChromeDriver(service, options);
//TestDriver.Manage().Window.Maximize();
//THIS JUST OPENS UP A NEW TAB. NOT A NEW WINDOW (IT WOULD SEEM MOST DOCUMENTATION SUGGESTS THAT IT SHOULD)
IJavaScriptExecutor jscript = Driver as IJavaScriptExecutor;
jscript.ExecuteScript("window.open();", "google.com.au");
//TRY USING THE SEND KEYS TECHNIQUE. NOTHING HAPPENS
var test = Driver.FindElement(By.TagName("html"));
test.SendKeys(Keys.Control + "n");
test.SendKeys(Keys.Control + "t");
//TRY AGAIN USING THE SEND KEYS TECHNIQUE USING A DIFFERENT TAG. NOTHING HAPPENS
var blah = Driver.FindElements(By.TagName("body"));
blah[0].SendKeys(Keys.Control + "t");
//TRY USING ACTIONS. NOTHING HAPPENS
Actions action = new Actions(Driver);
action.SendKeys(OpenQA.Selenium.Keys.Control + "n");
action.Build().Perform();
I may resort to AutoIt to open a browser if I have to, but one more dependency is not what I need. Documentation everywhere around the web seems to suggest than all the options I tried above should work...I suspect it may be a chromedriver issue of some kind.
Any ideas on how to achieve my goal would be greatly appreciated
UPDATE.
Arnons answer below lead me to the solution. If you are in a similar situation the best thing to do is just open up the browser console (from developers tools) and experiment with javascript until you get what you want. Then just execute that. In the end executing the following code has worked for me.
IJavaScriptExecutor jscript = Driver as IJavaScriptExecutor;
jscript.ExecuteScript("window.open('https://www.bing.com.au','_blank','toolbar = 0, location = 0, menubar = 0')");
The other alternative was to use Autoit, which I also got working, much easier than I did figuring out the javascript. But one less dependency is best :)
UPDATE2.
Further complications arise with trying to control the window as an independent browser window. I believe any new window created from a parent window, has the same process id (at least my testing has indicated so), and for all intense and purpose is treated as a tab in the selinium driver. I therefore conclude that certain things are just not possible (for example relocating the child browser window on the screen).
Your first attempt using ExecuteJavaScript was very close, but In order for it to open a new window instead of new tab, you should add the following arguments: `"_blank", "toolbar=0,location=0,menubar=0" to it.
See this question for more details.
I should have read the question better, here is my solution. Ended up using this for selecting windows that popped up after clicking a button but should work with swapping between windows.
//---- Setup Handles ----
//Create a Handle to come back to window 1
string currentHandle = driver.CurrentWindowHandle;
//Creates a target handle for window 2
string popupWindowHandle = wait.Until<string>((d) =>
{
string foundHandle = null;
// Subtract out the list of known handles. In the case of a single
// popup, the newHandles list will only have one value.
List<string> newHandles = driver.WindowHandles.Except(originalHandles).ToList();
if (newHandles.Count > 0)
{
foundHandle = newHandles[0];
}
return foundHandle;
});
//Now you can use these next 2 lines to continuously swap
//Swaps to window 2
driver.SwitchTo().Window(popupWindowHandle);
// Do stuff here in second window
//Swap back to window 1
driver.SwitchTo().Window(currentHandle);
// Do stuff here in first window
You need to explicitly tell Selenium which tab you wish to interact with, which in this case would be;
driver.SwitchTo().Window(driver.WindowHandles.Last());
I have this code:
IWebDriver driver = new FirefoxDriver();
driver.Manage().Window.Maximize();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(30));
//Go to the powerbi site
driver.Navigate().GoToUrl("https://powerbi.microsoft.com/en-us/");
//Go to the page with login form
driver.FindElement(By.XPath("html/body/div[2]/header/nav/div/ul[3]/li[1]/a")).Click();
//Fill in email field
driver.FindElement(By.XPath("//*[#id='cred_userid_inputtext']")).SendKeys("example#gmail.com");
When I launch this code on my computer everything works fine without errors. But when I launch this code on my boss's computer, sometimes it works and sometimes it doesn't.
When an error occurs, it's always on the last line of code. I don't remember exactly which error it is: InvalidElementStateException (when the target element is not enabled) or ElementNotVisibleException (when the target element is not visible).
I suppose the whole thing lies on the Click() method. The documentation says:
Click this element. If the click causes a new page to load, the Click() method will attempt to block until the page has loaded.
I don't quite understand how it attempts to block.
Seems like your input isn't always ready immediately after you click the button.
You should wait for it before sending the keys:
Try this instead of your last line:
WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0,0,5));
var input = wait.Until(ElementIsClickable(By.XPath("//*[#id='cred_userid_inputtext']")));
input.SendKeys("example#gmail.com");
In order to do that check, you should create a ElementIsClickable function, which returns a delegate, just as this answer shows:
public static Func<IWebDriver, IWebElement> ElementIsClickable(By locator)
{
return driver =>
{
var element = driver.FindElement(locator);
return (element != null && element.Displayed && element.Enabled) ? element : null;
};
}
Also, keep in mind that for using the WebDriverWait class you might need to import the Selenium.WebDriver and Selenium.Support packages into your project, just as this answer suggests.
It's coming occasional because sometimes it takes time to load element from DOM and which cause exception like InvalidElementStateException or ElementNotVisibleException.
I ran your snippets code.
It runs fine, try to separate action and find element.
WebElement element = driver.findElement(By.xpath(".//xyz"/);
element.sendkeys("data");
This could work.
We have a legacy remote system here that dont have webapi, webservice, ...
then we need to do integration by Selenium.
We need open multiple tabs from one master tab to do the extraction but when changing to desired tab and getting value by a css selector it get always the result from the fisrt tab.
Our system cant be opened on internet then i did the same with Google as an example, the same behaviour happens.
Its a bug or my fault ? Someone can see whats is wrong?
Below is a simplified version without error check, its minimal code.
Thanks a lot.
public static void testab()
{
IWebDriver driver = new FirefoxDriver();
driver.Navigate().GoToUrl("https://www.google.com/ncr");
IWebElement elmTxt = driver.FindElement(By.CssSelector("input#lst-ib"));
elmTxt.SendKeys("google" + Keys.Enter);
IWebElement elmQtdRes = driver.FindElement(By.CssSelector("div#resultStats"));
string strWebStat = elmQtdRes.Text;
IWebElement elmNewsLnk = driver.FindElement(By.CssSelector("a[href*='tbm=nws']"));
elmNewsLnk.SendKeys(Keys.Control + Keys.Return);
IWebElement elmBdy = driver.FindElement(By.CssSelector("body"));
elmBdy.SendKeys(Keys.Control + "2");
elmQtdRes = driver.FindElement(By.CssSelector("div#resultStats"));
string strNewStat = elmQtdRes.Text;
Console.WriteLine("Stat for WEB:[" + strWebStat + "]"); // prints stat for web - OK
Console.WriteLine("Stat for NEWS:[" + strNewStat + "]"); // prints stat for web - WRONG
}
WebDriver will not automatically switch focus to a new window or tab, so we have to tell it when to make the switch.
To switch to the new window/tab, try:
driver.SwitchTo().Window(driver.WindowHandles.Last());
Then, when you are finished on the new tab, close it and switch back to the primary window:
driver.Close();
driver.SwitchTo().Window(driver.WindowHandles.First());
Then from here, you can continue your test.
I'll add a quick disclaimer that I do not have Visual Studio installed on the machine I'm using at the moment and haven't tested the code above. This should, however get you in the right direction.
EDIT: Looking at your code a second time, this example above would replace the SendKeys() call to attempt to switch tab focus:
IWebElement elmBdy = driver.FindElement(By.CssSelector("body"));
elmBdy.SendKeys(Keys.Control + "2");
Using selenium in C# I am trying to open a browser, navigate to Google and find the text search field.
I try the below
IWebDriver driver = new InternetExplorerDriver(#"C:\");
driver.Navigate().GoToUrl("www.google.com");
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5));
IWebElement password = driver.FindElement(By.Id("gbqfq"));
but get the following error -
Unable to find element with id == gbqfq
This looks like a copy of this question that has already been answered.
I can show you what I've done, which seems to work well for me:
public static IWebElement WaitForElementToAppear(IWebDriver driver, int waitTime, By waitingElement)
{
IWebElement wait = new WebDriverWait(driver, TimeSpan.FromSeconds(waitTime)).Until(ExpectedConditions.ElementExists(waitingElement));
return wait;
}
This should wait waitTime amount of time until either the element is found or not. I've run into a lot of issues with dynamic pages not loading the elements I need right away and the WebDriver trying to find the elements faster than the page can load them, and this is my solution to it. Hope it helps!
You can try using a spin wait
int timeout =0;
while (driver.FindElements(By.id("gbqfq")).Count == 0 && timeout <500){
Thread.sleep(1);
timeout++;
}
IWebElement password = driver.FindElement(By.Id("gbqfq"));
this should help make sure that the element has actually had time to appear.
also note, the "gbqfq" id is kinda a smell. I might try something more meaningful to match on than that id.