I am making a bot that list all the given assembled letters to make the players connect or build a word around that given value of assembled letters, im very new to selenium and still grasping the best practices thanks in advance. (https://jklm.fun "BombParty")
https://i.stack.imgur.com/wGyMd.png
What we want to achieve:
//locate the element (the one the center of that bomb)
//extract the elements displayed value (the label)
//Console Log that value
My Code:
ChromeOptions options = new ChromeOptions(); //creating chrome driver options to add some commands to remove the message "This is automated . . ."
options.AddAdditionalCapability("useAutomationExtension", true);
options.AddExcludedArgument("enable-automation");
options.AddArgument("window-size=1200x600");
var driver = new ChromeDriver(options); //declear our driver for us to automate and control
driver.Navigate().GoToUrl("https://jklm.fun/QVVC"); // go to our targeted uri
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(25); // wait for sometime to give our client to load
// let our user enter the username or join a game
while (true) // loop our funtion to locate and extract the given word
{
try
{
driver.FindElements(By.CssSelector("div.syllable")); //we did a FindElements because the label can change value over time and state another syllable
Console.WriteLine("Success!");
}
catch
{
Console.WriteLine("Failed!");
}
}
The Output of my Code:
Success!
What I Have tried:
var word = driver.FindElement(By.CssSelector("div.syllable"));
Console.WriteLine(word.Text.ToString());
The Result: Failed!
Update:
So i tried to get the value after it finds it and i will find it again,it was a success but it only returns this string, how to fix this?
The update
I try to "read and click" an Element that is not present on the Screen.
My current quick & dirty solution is to zoom the body to 90%, than all works fine in this case. But this cannot be the right solution.
IJavaScriptExecutor js = (IJavaScriptExecutor)webdriver;
js.ExecuteScript(string.Format("document.body.style.zoom='{0}%'", 90));
The Webside i am working with is: https://eatradingacademy.com/software/forex-historical-data/
Scroll a little down, push "Load Data" and in the table down of this Button i am reading something out and download Files.
I searched around and found the "Actions". There came no error up, but also nothing happens ... The XPath is correct.
var element11 = webdriver.FindElement(By.XPath("//*[#id='table-acquisition']/ tr[7]/td[2]"));
Actions actions = new Actions(webdriver);
actions.MoveToElement(element11);
actions.Perform();
//element11.Click();
Also I found some Code to scroll a little bid down, again no error, but also no effect (no scrolling).
IJavaScriptExecutor js = (IJavaScriptExecutor)webdriver;
js.ExecuteScript("javascript:window.scrollBy(250,350)");
What am i doing wrong in this both code examples?
Or what is the solution to scroll to an Element that is currently not present shown on the Screen?
The complete Table is only readable if it is present on the Screen.
Who can help me?
Edit 1:
For more details in my question, here is c+p together was will be done in my code:
ChromeDriverService service = ChromeDriverService.CreateDefaultService();
service.HideCommandPromptWindow = false;
//// change Standart-Download-Ordner
//ChromeOptions options = new ChromeOptions();
//var downloadDirectory = GlobalVars.RootPath + GlobalVars.strSymbol;
//options.AddUserProfilePreference("download.default_directory", downloadDirectory);
//options.AddUserProfilePreference("download.prompt_for_download", false);
//options.AddUserProfilePreference("disable-popup-blocking", "true");
//// Selenium Driver starten:
//webdriver = new ChromeDriver(service, options);
webdriver = new ChromeDriver(service);
// Fenster auf Vollbild, damit keine Elemente verdecht werden
webdriver.Manage().Window.Maximize();
webdriver.Navigate().GoToUrl("https://eatradingacademy.com/software/forex-historical-data/");
// deactivate Request --NOT YET-- "Would you like to receive notifications on latest updates?"
webdriver.FindElement(By.Id("webpushr-deny-button")).Click();
//// Current solution: Zoom Browser Body
//IJavaScriptExecutor js = (IJavaScriptExecutor)webdriver;
//js.ExecuteScript(string.Format("document.body.style.zoom='{0}%'", 90));
// change to right iFrame
webdriver.SwitchTo().Frame(webdriver.FindElement(By.Id("data-app-frame")));
// Navigate to "Settings" ...
var objBrowserLink = webdriver.FindElement(By.XPath("//a[#class='nav-link panel-switch' and contains(text(), 'Settings')]"));
Actions actions = new Actions(webdriver);
actions.MoveToElement(objBrowserLink);
actions.Perform();
objBrowserLink.Click();
// Change settings
webdriver.FindElement(By.Id("btn-reset-settings")).Click();
webdriver.FindElement(By.XPath("//select[#id='select-max-bars']/option[contains(text(), '200 000')]")).Click();
webdriver.FindElement(By.XPath("//select[#id='select-timezone']/option[contains(text(), '(GMT+02:00) Helsinki, Kiev, Riga, Sofia, Tallinn, Vilnius')]")).Click();
webdriver.FindElement(By.Id("input-server")).Clear();
webdriver.FindElement(By.Id("input-server")).SendKeys("AM Premium Data");
// Navigate to -Acquisition-
var objBrowserLink = webdriver.FindElement(By.XPath("//a[#class='nav-link panel-switch' and contains(text(), 'Acquisition')]"));
Actions actions = new Actions(webdriver);
actions.MoveToElement(objBrowserLink);
actions.Perform();
objBrowserLink.Click();
// Select Format to Download
webdriver.FindElement(By.XPath("//select[#id='select-format']/option[contains(text(), 'Expert Advisor Studio (JSON)')]")).Click();
// Click Button Load Data
webdriver.FindElement(By.Id("btn-load-data")).Click();
// --> Here starts my current problem:
// #####################################
// Test if switch will help again
//webdriver.SwitchTo().Frame(webdriver.FindElement(By.Id("data-app-frame")));
var element11 = webdriver.FindElement(By.XPath("//*[#id='table-acquisition']/ tr[7]/td[2]"));
Actions actions = new Actions(webdriver);
actions.MoveToElement(element11);
actions.Perform();
element11.Click();
//Thread.Sleep(1000);
// now follows a for ... The 2 lines down shoud do what is needed ...
//for (int i = 1; i < 8; i++)
string strXPath_Download_Table = "//*[#id='table-acquisition']/ tr[7]/td[6]";
webdriver.FindElement(By.XPath(strXPath_Download_Table)).Click();
I can't seem to get past this exception on my coded UI project for a window dialog box. I've tried using always search and some other options. I was trying to use the option of open a window dialog button but that didn't seem to work since i did not see the open button only "OK" and a few ones that didn't pertain to what i was trying to do.
I see one of my window is returning 5 windows, I'm trying to use the code Order Of overcation but that doesn't seem to work.
Currently here is my latest code which is still not working and still giving me the same exception error
WinWindow myDialogBox = new WinWindow();
myDialogBox.FilterProperties.Add(WinWindow.PropertyNames.OrderOfInvocation, "5");
myDialogBox.SearchConfigurations.Add(SearchConfiguration.AlwaysSearch);
myDialogBox.SearchProperties[WinWindow.PropertyNames.ClassName] = "DirectUIHWND";
myDialogBox.SearchProperties[WinWindow.PropertyNames.ControlId] = "0";
myDialogBox.DrawHighlight();
WinWindow MyOpbenButton = new WinWindow(myDialogBox);
// myDialogBox.SearchProperties.Add(WinWindow.PropertyNames.OrderOfInvocation, "0");
MyOpbenButton.SearchConfigurations.Add(SearchConfiguration.AlwaysSearch);
MyOpbenButton.SearchProperties[WinWindow.PropertyNames.Name] = "&Open";
MyOpbenButton.SearchProperties[WinWindow.PropertyNames.ClassName] = "Button";
//MyOpbenButton.SearchProperties[WinWindow.PropertyNames.ControlId] = "0";
MyOpbenButton.DrawHighlight();
//Testing this window produces 5 window with the same name and
control ID.
WinWindow matchingWindows = new WinWindow(myDialogBox);
matchingWindows.SearchProperties.Add("Name", "&Open");
// matchingWindows.SearchProperties.Add("ControlId", "0");
matchingWindows.SearchProperties.Add("ClassName", "Button");
UITestControlCollection windowsFound = matchingWindows.FindMatchingControls();
WinPane MyOpbenPane = new WinPane(MyOpbenButton);
MyOpbenPane.SearchConfigurations.Add(SearchConfiguration.AlwaysSearch);
//MyOpbenPane.SearchProperties[WinPane.PropertyNames.Name] = "Open";
MyOpbenPane.SearchProperties[WinPane.PropertyNames.ClassName] = "Button";
// var myDialog = sharedControls.UIWindowsInternetExploWindow.UIWindowsInternetExplo_Open_Save_Dialog_LinksPage.UIItemWindow;
MyOpbenPane.DrawHighlight();
return MyOpbenPane;
The error message that this is producing is the following:
Another control is blocking the control. Please make the blocked
control visible and retry the action. Additional Details:
\r\nTechnologyName: 'MSAA'\r\nName: '&Open'\r\nClassName:
'Button'\r\nControlType: 'Window'\r\n
I used the test builder to get around this issue.
I found that the dialog screen was being captured with the
classname of 32770. I also found that i could not pass off my browser window to window from there i hand coded the remaining screen using the test builder.
here is the code below.
WinWindow window = new WinWindow();
window.SearchConfigurations.Add(SearchConfiguration.AlwaysSearch);
window.SearchConfigurations.Add(SearchConfiguration.VisibleOnly);
window.SearchProperties[WinWindow.PropertyNames.ClassName] = "#32770";
window.SearchProperties[WinWindow.PropertyNames.Name] = "Windows Internet Explorer";
window.WindowTitles.Add("Windows Internet Explorer");
//window.DrawHighlight();
WinCustom myDialogBox = new WinCustom(window);
myDialogBox.SearchConfigurations.Add(SearchConfiguration.VisibleOnly);
myDialogBox.SearchConfigurations.Add(SearchConfiguration.AlwaysSearch);
myDialogBox.SearchProperties[WinCustom.PropertyNames.ControlType] = "Dialog";
myDialogBox.SearchProperties[WinCustom.PropertyNames.Name] = "Windows Internet Explorer";
myDialogBox.WindowTitles.Add("Windows Internet Explorer");
//myDialogBox.DrawHighlight();
WinWindow myDialogwindow = new WinWindow(window);
myDialogwindow.SearchConfigurations.Add(SearchConfiguration.VisibleOnly);
myDialogwindow.SearchConfigurations.Add(SearchConfiguration.AlwaysSearch);
myDialogwindow.SearchProperties[WinWindow.PropertyNames.AccessibleName] = "Windows Internet Explorer";
myDialogwindow.SearchProperties[WinWindow.PropertyNames.ClassName] = "DirectUIHWND";
myDialogwindow.WindowTitles.Add("Windows Internet Explorer");
return myDialogwindow;
I run into this a lot. I have an application on which the tabs always get reported as hidden, even though they're clearly visible. What has worked well for me so far has been to use keyboard.sendkeys to send keystrokes that select the tab.
I've looked extensively through Google and Stackoverflow, but i cant find a good way to implement keeping the browser open after a run and reuse it for the next run. I have it login, get text, but it closes after. I want to keep it open so I dont have relaunch the browser, login again and take more time than necessary. Simply want to use that same webpage, refresh/update the page, and get the new text(its dhtml). I have it to run every 10 seconds or so. Here what i have so far.
using (var driver = new ChromeDriver(""))
{
driver.Navigate().GoToUrl(#"");
// Get User Name field, Password field and Login Button
var userNameField = driver.FindElementByName("j_username");
var userPasswordField = driver.FindElementByName("j_password");
var loginButton = driver.FindElementByName("Submit");
// Type user name and password
userNameField.SendKeys("");
userPasswordField.SendKeys("");
// and click the login button
loginButton.Click();
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
{
return d.FindElement(By.ClassName(""));
});
// Extract resulting message and save it into result.txt
string result = driver.FindElement(By.ClassName("")).Text;
}
I'm having an issue with automating the process of downloading a file from a website. The website has a Java button, that when clicked, triggers the download of an Excel file. I'm using the most recent build of Watin (v2.1).
I've managed to get Watin to log into the website, navigate to the appropriate page, change parameters on the page, and click the button to start the download.
However, when the download has completed, the IE9 download box appears, and nothing happens, until Watin timesout.
I'd appreciate any suggestions as I can't see any way of downloading a file, or getting it to save the file. Even if it passed 'Alt+S' to the page, that would save it. I've tried running it through WatinTestRecorder and that doesn't prompt for saving.
using (var browser = new IE(sLogin))
{
browser.AddDialogHandler(new OKDialogHandler());
browser.AddDialogHandler(new DialogHandlerHelper());
browser.AddDialogHandler(new ConfirmDialogHandler());
browser.AddDialogHandler(new ReturnDialogHandlerIe9());
browser.TextField(Find.ByName("txtUserID")).TypeText("username");
browser.TextField(Find.ByName("txtPassword")).TypeText("password");
browser.Button(Find.ByName("btnLogin")).Click();
browser.WaitForComplete();
browser.GoTo(targetUri);
browser.SelectList("ctl00_phFormContent_ucOptionParam0_lst").SelectByValue("4");
browser.Button(Find.ByName("ctl00$phFormButtonBar$btnRun")).Click();
browser.WaitForComplete();
//Some code to download the file here!
}
This should be supported since version 1.1.0.4000. The release notes for that version aren't online anymore (http://watin.org/documentation/), but I found it in Googles cache (http://svn6.assembla.com/svn/ci-samples/dotnet/watir/website/releasenotes-1-1-0-4000.html)
It should be something like:
using(IE ie = new IE(someUrlToGoTo))
{
FileDownloadHandler fileDownloadHandler = new FileDownloadHandler(fullFileName);
ie.AddDialogHandler(fileDownloadHandler);
ie.Link("startDownloadLinkId").Click();
fileDownloadHandler.WaitUntilFileDownloadDialogIsHandled(15);
fileDownloadHandler.WaitUntilDownloadCompleted(200);
}
EDIT:
After the comments below, this answer was accepted. So I'm assuming the following code works (which is taken from the link to SourceForge in my last comment, notice the ClickNoWait):
using(IE ie = new IE(someUrlToGoTo))
{
FileDownloadHandler fileDownloadHandler = new FileDownloadHandler(fullFileName);
ie.AddDialogHandler(fileDownloadHandler);
ie.Link("startDownloadLinkId").ClickNoWait();
fileDownloadHandler.WaitUntilFileDownloadDialogIsHandled(15);
fileDownloadHandler.WaitUntilDownloadCompleted(200);
}
The accepted answer did not work for me because IE 9 pops up a "Notification" you have to navigate before you can get to the actual Save As dialog (and WatiN cannot handle notifications automatically). I followed Borris Pavlov's link which did a good job showing the way. I cleaned up the code a bit that was posted there and this was the resulting file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WatiN.Core;
using WatiN.Core.Native.Windows;
using System.Threading;
using System.Windows.Automation;
namespace MyProject
{
public static class BrowserExtensionMethods
{
public static void DownloadIeFile(this IE browser,string saveAsFilename=null)
{
// see information here (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633515(v=vs.85).aspx)
Window windowMain = new Window(NativeMethods.GetWindow(browser.hWnd, 5));
TreeWalker dialogElementTreeWalker = new TreeWalker(Condition.TrueCondition);
AutomationElement mainWindow = dialogElementTreeWalker.GetParent(AutomationElement.FromHandle(browser.hWnd));
Window windowDialog = new Window(NativeMethods.GetWindow(windowMain.Hwnd, 5));
// if doesn't work try to increase sleep interval or write your own waitUntill method
Thread.Sleep(1000);
windowDialog.SetActivate();
AutomationElementCollection dialogElements = AutomationElement.FromHandle(windowDialog.Hwnd).FindAll(TreeScope.Children, Condition.TrueCondition);
if (string.IsNullOrEmpty(saveAsFilename))
{
ClickSave(dialogElements);
}
else
{
ClickSaveAs(mainWindow, dialogElements,saveAsFilename);
}
}
private static void ClickSaveAs(AutomationElement mainWindow, AutomationElementCollection dialogElements,string filename)
{
foreach (AutomationElement element in dialogElements)
{
if (element.Current.Name.Equals("Save"))
{
AutomationElementCollection dialogSubElements = element.FindAll(TreeScope.Children, Automation.ControlViewCondition);
InvokePattern clickPatternForSaveDropdown = (InvokePattern)dialogSubElements[0].GetCurrentPattern(AutomationPattern.LookupById(10000));
clickPatternForSaveDropdown.Invoke();
Thread.Sleep(3000);
AutomationElementCollection dialogElementsInMainWindow = mainWindow.FindAll(TreeScope.Children, Condition.TrueCondition);
foreach (AutomationElement currentMainWindowDialogElement in dialogElementsInMainWindow)
{
if (currentMainWindowDialogElement.Current.LocalizedControlType == "menu")
{
// first array element 'Save', second array element 'Save as', third second array element 'Save and open'
InvokePattern clickMenu = (InvokePattern)currentMainWindowDialogElement.FindAll(TreeScope.Children, Condition.TrueCondition)[1].GetCurrentPattern(AutomationPattern.LookupById(10000));
clickMenu.Invoke();
Thread.Sleep(5000);
ControlSaveDialog(mainWindow, filename);
break;
}
}
}
}
}
private static void ClickSave(AutomationElementCollection dialogElements)
{
foreach (AutomationElement element in dialogElements)
{
// You can use "Save ", "Open", ''Cancel', or "Close" to find necessary button Or write your own enum
if (element.Current.Name.Equals("Save"))
{
// if doesn't work try to increase sleep interval or write your own waitUntil method
// WaitUntilButtonExsist(element,100);
Thread.Sleep(1000);
AutomationPattern[] automationPatterns = element.GetSupportedPatterns();
// replace this foreach if you need 'Save as' with code bellow
foreach (AutomationPattern currentPattern in automationPatterns)
{
// '10000' button click event id
if (currentPattern.Id == 10000)
{
InvokePattern click = (InvokePattern)element.GetCurrentPattern(currentPattern);
click.Invoke();
}
}
}
}
}
private static void ControlSaveDialog(AutomationElement mainWindow, string path)
{
//obtain the save as dialog
//*** must disable throwing of the NonComVisibleBaseClass "exception" for this to work in debug mode:
// 1. Navigate to Debug->Exceptions...
// 2. Expand "Managed Debugging Assistants"
// 3. Uncheck the NonComVisibleBaseClass Thrown option.
// 4. Click [Ok]
//***copied from http://social.msdn.microsoft.com/Forums/en-US/27c3bae8-41fe-4db4-8022-e27d333f714e/noncomvisiblebaseclass-was-detected?forum=Vsexpressvb
var saveAsDialog = mainWindow.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Save As"));
//var saveAsDialog = mainWindow.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "[#] Save As [#]")); //needed if using sandboxie
//get the file name box
var saveAsText = saveAsDialog
.FindFirst(TreeScope.Descendants,
new AndCondition(
new PropertyCondition(AutomationElement.NameProperty, "File name:"),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit)))
.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
//fill the filename box
saveAsText.SetValue(path);
Thread.Sleep(1000);
//find the save button
var saveButton =
saveAsDialog.FindFirst(TreeScope.Descendants,
new AndCondition(
new PropertyCondition(AutomationElement.NameProperty, "Save"),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button)));
//invoke the button
var pattern = saveButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
pattern.Invoke();
}
}
}
See the comment in the ControlSaveDialog method for info on how to make this work as a debug build (VS settings).
I actually only tested the "Save As" operation so I hope the other works (it seems that the original poster added the "Save As" as an afterthought so my guess is that he tested the "Save" operation more thoroughly).
To call this you can use some code like:
Link lastMp4Link = mp4Links[mp4Links.Count - 1]; //mp4Links is a WatiN.Core.LinkCollection
lastMp4Link.Click();
browser.DownloadIeFile(string.Format(#"c:\temp\myFile.blah")); //"browser" is a WatiN.Core.IE object
I just got word from the Watin-users mailing list that FileDownloadHandler is broken with IE9. There is no fix yet, however I uninstalled IE9 (roll back to IE8) and it has the old style dialog that is handled by WatiN.
Watin can't find download dialog and dialog buttons. It can resolve with this.
How to test file download with Watin / IE9?
See comments
After many revisions using WaitN, I ended up using Selenium. It gives you a ton more control over what is being processed and used and allows you to use more modern web browsers.