On the following website: https://netbank.nedsecure.co.za
there is an inputbox for profile number.
However, Selenium is unable to find the element and throws a NoSuchElementException. I have tried what is suggested in other Stackoverflow questions, regarding using a wait to ensure the page has loaded.
Here is some code that fails:
var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var driver = new ChromeDriver(path);
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(20);
driver.Url = "https://netbank.nedsecure.co.za";
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));
wait.Until(drv => drv.FindElement(By.Id("ProfileId")));
var profileInput = driver.FindElementById("ProfileId");
The page had a <frameset> with a <frame> element.
The issue is resolved by switching the driver to the frame
driver.SwitchTo().Frame("frameMain");
Profile Number, PIN & Password & Login button are present on a frame. You need to switch on a frame before performing any action on it. Please use below code to switch on your frame.
driver.SwitchTo().Frame(driver.FindElement(By.id("frameset")));
Related
Hi.
How can I click on 'Allow' button? I really can't find any solution in the internet. I don't want to use c++ hooks or simulate mouse clicks by coordinates. Is there any good way to allow this notification?
new ChromeOptions.AddUserProfilePreference("profile.default_content_setting_values.automatic_downloads", 2);
doesn't help
Found two solutions:
1) Thanks for #Floren 's answer: C# selenium chromedriver click on Allow store files on this device
There is an argument for Chromium --unlimited-storage
Chromium source code reference:
// Overrides per-origin quota settings to unlimited storage for any
// apps/origins. This should be used only for testing purpose.
const char kUnlimitedStorage[] = "unlimited-storage";
# Prevent the infobar that shows up when requesting filesystem quota.
'--unlimited-storage',
C# usage:
var chromeOptions = new ChromeOptions();
chromeOptions.AddArgument("--unlimited-storage");
var driver = new ChromeDriver(chromeOptions);
2) #Simon Mourier's answer C# selenium chromedriver click on Allow store files on this device
Click on Allow button using .NET UIAutomation
var andCondition = new AndCondition(new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button), new PropertyCondition(AutomationElement.NameProperty, "Allow"));
AutomationElement chromeWindow = AutomationElement.FromHandle(_windowPointer); // IntPtr type
var buttonsFound = chromeWindow.FindAll(TreeScope.Descendants, andCondition);
if (buttonsFound.Count > 0)
{
var button = buttonsFound[0];
var clickPattern = button.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
clickPattern.Invoke();
}
You can't, this is an OS level dialogue, not something inside the DOM.
The way to get around it is by using desired capabilities to configure chrome to not show this dialogue.
I'm going to suggest
ChromeOptions options = new ChromeOptions();
options.AddUserProfilePreference("download.prompt_for_download", 0);
options.AddUserProfilePreference("settings.labs.advanced_filesystem", 1);
Other potential commands to add the options if AddUserProfilePreference doesn't work would be:
AddLocalStatePreference
AddAdditionalChromeOption
AddAdditionalCapability
For more details about desired capabilities and chrome have a look at:
The ChromeOptions documentation
This list of command line switches, or the command line switched defined directly in code.
The preferences defined directly in code
The ChromeOptions class in the Selenium codebase
var chromeOptions = new ChromeOptions();
var downloadDirectory = #"C:\Users\";
chromeOptions.AddUserProfilePreference("download.default_directory", downloadDirectory);
chromeOptions.AddUserProfilePreference("download.prompt_for_download", false);
chromeOptions.AddUserProfilePreference("disable-popup-blocking", "true");
chromeOptions.AddUserProfilePreference("profile.default_content_setting_values.automatic_downloads", 1);
IWebDriver _driver = new ChromeDriver(chromeOptions);
Can you try with this one ?
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());
From what I understand, the default action of when the Webdriver finds an element is to scroll such that the element is as far up the top of the page as possible. This is an issue because the website I'm working on has a header so every time I try to click on a button, it will instead click on the header. Thus, I want to change the scroll setting so that the element will be at the bottom of the page.
From reading this I was able to find what I wanted to set, however, I'm unable to set the DesiredCapabilites or ChromeOptions when I initialise the ChromeDriver. Could some provide code/steps to do this please?
You can use something like this
var chromeOptions = new ChromeOptions();
chromeOptions.AddUserProfilePreference("intl.accept_languages", "en");
chromeOptions.AddUserProfilePreference("disable-popup-blocking", "true");
var driver = new ChromeDriver(chromeOptions);
Edit-2
If the option you want to set doesn't work for you then try using actions
var elem = driver.FindElements(By.Id("your element"));
Actions action = new Actions(driver);
action.MoveToElement(elem).Click(elem).Perform();//move to list element that needs to be hovered
Edit-3
If the above also doesn't work then your next option is to use Javascript
var elem = driver.FindElements(By.Id("your element"));
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
var success = js.ExecuteScript("arguments[0].click(); return true", elem);
As far as I know you can't change everything through addarguments.
There is a list of what you can do in the Github page. but I have a better solution. you can make your own default settings and save it as a chrome profile. for example I didn't find anything to change homepage with code but this works fine for almost evwerything.
you can use this code :
options.AddArguments( #"user-data -dir=C:\Users\kian\AppData\Local\Google\Chrome\User Data");
options.AddArgument("--profile-directory=Default");
make sure you write the right path and right profile name.
to check the profile name you can go to properties.
properties
you will see the profile name.
there is a good guide for what else u can do in link.
I am testing data flow for a client's website. It has advertisements that take substantially longer to load than the data elements of each page that I would like to test with Selenium commands.
I don't have control over the ads and can't silence them.
I would like to navigate each page with clicks prior to the complete page loading. I know that this is possible because I can do it manually using the mouse. However, despite my attempts the stubborn chromeDriver will not begin automation until the entire page is loaded.
I am using C# .Net 4.6.1, chrome32_55.0.2883.75, and Selenium version 3.0.1.0.
Further, I am using the recommended Selenium page object model. I implemented WaitForLoad() like this:
public override void WaitForLoad()
{
_isLoaded = Wait.Until(d =>
{
lock (d)
{
SwitchToSelf();
return PageRegex.IsMatch(Session.Driver.PageSource);
}
});
}
The PageRegex above will work but only after the full page is loaded. Which is frustrating because I can visually see that the text string that the PageRegex is designed to parse is on the screen. This leads me to believe that there is a setting elsewhere, perhaps while I am configuring ChromeDriver, that would enable me to parse the Session.Driver.PageSource prior to it being completely loaded.
This is how I am instancing the ChromeDriver:
var options = new ChromeOptions();
options.AddArguments("test-type");
options.AddArgument("incognito"); // works
options.AddArgument("--disable-bundled-ppapi-flash"); // works! this turns off shockwave
options.AddArgument("--disable-extensions"); // works
options.AddArguments("--start-fullscreen");
string workFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) +
"\\SHARED";
options.BinaryLocation = workFolder + #"\Chrome32\chrome32_55.0.2883.75\chrome.exe";
var driver = new ChromeDriver(options);
driver.Manage().Cookies.DeleteAllCookies();
return driver;
To interact with the page before it has finished loading, you can either lower the timeout and catch the exception:
IWebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromMilliseconds(500));
try {
driver.Navigate().GoToUrl("http://www.deelay.me/5000/http://www.deelay.me/");
} catch (OpenQA.Selenium.WebDriverTimeoutException) { }
// waits for an element
var body = wait.Until(ExpectedConditions.ElementExists(By.CssSelector("body")));
Or you can disable the waiting by setting the page load stategy to none :
var options = new ChromeOptions();
options.AddAdditionalCapability("pageLoadStrategy", "none", true);
IWebDriver driver = new ChromeDriver(options);
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
driver.Navigate().GoToUrl("http://www.deelay.me/5000/http://www.deelay.me/");
// waits for an element
var body = wait.Until(ExpectedConditions.ElementExists(By.CssSelector("body")));
Have you tried with ElementToBeClickable or VisibilityOfElementLocated methods of ExpectedConditions class. I think it should work in the scenario you mentioned.
WebDriverWait wdw = new WebDriverWait(driver, TimeSpan.FromSeconds(120));
wdw.Until(ExpectedConditions.ElementToBeClickable(By.Id("ElementId")));
I would like to navigate each page with clicks prior to the complete
page loading
Do I understand you right that you want to click on some links while the page is still loading?
If you know which elements you are going to click, maybe you can do the same as in this question How to click on an element before the page is fully loaded i'm stuck, it takes too much time until loading completed
currently I have the following code using selenium and phantomjs in c#:
public class Driver
{
static void Main()
{
using (var driver = new PhantomJSDriver())
{
driver.Navigate().GoToUrl("https://www.website.com/");
driver.Navigate().GoToUrl("https://www.website.com/productpage/");
driver.ExecuteScript("document.getElementById('pdp_selectedSize').value = '10.0'"); //FindElementById("pdp_selectedSize").SendKeys("10.0");
driver.ExecuteScript("document.getElementById('product_form').submit()");
driver.Navigate().GoToUrl("http://www.website/cart/");
Screenshot sh = driver.GetScreenshot();
sh.SaveAsFile(#"C:\temp\test.jpg", ImageFormat.Png);
}
}
}
My objective is to be able to add a product to my cart and then checkout automatically. The screenshot is just included to test whether the code was successfully working. My first issue is that I often get an error that it cannot find the element with product id "pdp_selectedSize". I'm assuming this is because the the webdriver hasn't loaded the page yet, so I'm looking for a way to keep checking until it finds it without having to set a specific timeout.
I'm also looking for faster alternatives to use instead of a headless browser. I used a headless browser instead of http requests because I need certain cookies to be able to checkout on the page, and these cookies are set through javascript within the page. If anyone has a reccommendation for a faster method, it would be greatly appreciated, thanks!
For your first question, it would behoove you to look into using ExpectedConditions' which is part of theWebDriverWaitclass inSelenium`. The following code sample was taken from here and only serves as a reference point.
using (IWebDriver driver = new FirefoxDriver())
{
driver.Url = "http://somedomain/url_that_delays_loading";
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement myDynamicElement = wait.Until<IWebElement>(d =>
d.FindElement(By.Id("someDynamicElement")));
}
More on WebDriverWaits here.
As to your second question, that is a really subjective thing, in my opinion. Headless Browsers aren't necessarily any faster or slower than a real browser. See this article.