I use the Drag and drop code below to drag a picture in to a photofield. This works fine in InternetExplorer, but doesn't work in Firefox or Chrome.
I don't understand why not.
As you can see in the code below I've tried a lot of different ways to do the drag and drop, but none of them works.
The main problem is that the target is not updated after releasing the image.
I see the drop happen but no update.
Does anyone have any idea why this is? I'm using C# and the latest Selenium driver 2.39, chrome driver 2.8.
public static void DoDragAndDrop(IWebDriver driver, string dragImageId, string dropFieldId)
{
Console.WriteLine("Drag and drop image '{0}' to the editor {1}..", dragImageId, dropFieldId);
IWebElement dragElement = WebDriverExtensions.TryFindElement(By.Id(dragImageId));
IWebElement dropElement = WebDriverExtensions.TryFindElement(By.Id(dropFieldId));
if(dragElement == null)
Console.WriteLine("dragElement is null");
if(dropElement == null)
Console.WriteLine("dropElement is null");
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].scrollIntoView();", dragElement);
Thread.Sleep(500);
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].scrollIntoView();", dropElement);
Thread.Sleep(200);
Console.WriteLine("Drag and drop 1");
var builder1 = new Actions(driver);
builder1.MoveToElement(dragElement).ClickAndHold();
builder1.MoveToElement(dropElement).Build().Perform();
Thread.Sleep(2000);
Console.WriteLine("Drag and drop 2");
var builder2 = new Actions(driver);
builder2.DragAndDrop(dragElement, dropElement);
Thread.Sleep(2000);
Console.WriteLine("Drag and drop 3");
var builder3 = new Actions(driver);
builder3.DragAndDrop(dragElement, dropElement).Build().Perform();
IAction dragAndDrop = builder3.ClickAndHold(dragElement)
.MoveToElement(dropElement)
.Release(dropElement)
.Build();
dragAndDrop.Perform();
Thread.Sleep(2000);
Thread.Sleep(1000);
Console.WriteLine("Drag and drop succeeded..");
}
This is how I've got it working in FireFox now. Chrome still fails.
The only difference is that I've added offsets in the MoveToElement method, as seen in The Rookies comment.
var builder = new Actions(driver);
builder.ClickAndHold(dragElement);
builder.MoveToElement(dropElement, 5, 5);
builder.Perform();
Thread.Sleep(250);
builder.Release(dropElement);
builder.Perform();
Tried below sample code with chromedriver:2.15, chrome:v43 and is working fine as expected.
Sample Code:
System.setProperty("webdriver.chrome.driver","drivers/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(1,TimeUnit.MINUTES);
driver.get("http://jqueryui.com/droppable");
driver.switchTo().frame(0);
WebElement dragElement = driver.findElement(By.id("draggable"));
WebElement dropElement = driver.findElement(By.id("droppable"));
Actions builder = new Actions(driver);
builder.clickAndHold(dragElement).moveToElement(dropElement).release().build().perform();
For firefox you can use following but it is in ruby
panel = driver.find_element(:id, ' (panel around the picture)')
target = panel.find_element(:xpath, ' ')
source = panel.find_element(:xpath, ' ')
driver.action.click_and_hold(source).move_to(target, 400, 150).release(target).perform
Hope it helps
ChromeDriver doesn't yet support the Actions commands. The Java
language binding translates the Actions requests into corresponding
mouse events before sending them to ChromeDriver, however there is no
guarantee the translated mouse events are completely equivalent to the
original Actions request.
Source: Chromium bugtacker
Related
How can I use click event on multiple page in the same test cases on Selenium and C#
For example:
Go to Google Homepage.
Search the resulting Test
Click on the Search button,
The user gets Redirected to the Searched Result page, but when I am trying to select any link it showing error.
public void opengoogle()
{
ChromeOptions option = new ChromeOptions();
option.AddArgument("--headless");
ChromeDriver wd = new ChromeDriver(option);
try
{
wd.Navigate().GoToUrl("https://www.google.co.in/");
Thread.Sleep(2000);
wd.FindElement(By.CssSelector("#lst-ib")).Click();
Thread.Sleep(2000);
wd.FindElement(By.CssSelector("#lst-ib")).Click();
wd.FindElement(By.CssSelector("#lst-ib")).Clear();
wd.FindElement(By.CssSelector("#lst-ib")).SendKeys("Test");
wd.FindElement(By.CssSelector("#lst-ib")).Submit();
}
finally { }
public void TestMethod1()
{
ChromeOptions option = new ChromeOptions();
option.AddArgument("--headless");
ChromeDriver webDriver = new ChromeDriver(option);
try
{
webDriver.Navigate().GoToUrl("https://www.google.lk/");
WebDriverWait wait = new WebDriverWait(webDriver, new TimeSpan(0, 0, 0, 30));
IWebElement searchTextField= wait.Until(ExpectedConditions.ElementToBeClickable(By.Id("lst-ib")));
searchTextField.SendKeys("Test");
IWebElement searchButton = wait.Until(ExpectedConditions.ElementToBeClickable(By.CssSelector(".lsb")));
searchButton.Click();
wait.Until(ExpectedConditions.TitleContains("Test"));
IWebElement searchResultLink= wait.Until(ExpectedConditions.ElementToBeClickable(By.CssSelector("a[href='http://www.speedtest.net/']")));
searchResultLink.Click();
}
finally { }
}
You can try above code.
It explains following process.
First move to Google search page.
Insert "Test" in to search text field.
Then click on Google search button.
After Navigate to search results page, click on "www.speedtest.net" link.
You can try out this code:
ChromeOptions option = new ChromeOptions();
option.AddArgument("--headless");
ChromeDriver wd = new ChromeDriver(option);
wd.Navigate().GoToUrl("https://www.google.co.in/");
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromMinutes(1));
wait.Until(ExpectedConditions.ElementToBeClickable(By.Name("q")));
wd.FindElement(By.Name("q")).SendKeys("Test"+Keys.RETURN);
wait.Until(ExpectedConditions.VisibilityOfElementLocated(By.CssSelector("a[href='http://www.speedtest.net/']")));
driver.FindElement(By.CssSelector("a[href='http://www.speedtest.net/']")).Click();
P.S :
1. I'm not good in C# though I've tried to convert a java code to C#. Hope this will be helpful for you.
2. This will always open the speedtest.net website. If you want something else, you can have it by replacing the cssSelector which I have written.
I have two instances of the ChromiumWebBrowser in my WinForms project (Visual Studio 2012). My goal is to have the second browser instance "copy" the behavior of the user input in the first browser instance. I can successfully retrieve the input from the first browser, and I managed to hook up Selenium in the project as well.
However, I'm having one issue. Whenever Selenium sends its commands, the first browser is the one that responds to them. For the life of me, I can't seem to figure out how to make the second browser respond. Whenever I completely remove the first browser, the second one starts responding correctly, but adding the first browser again will make only have the first browser use the Selenium commands. I even tried to switch out the moments the browsers are added to the form, but to no avail: whenever there are two available, the wrong one is responsive.
Relevant code:
public BrowserManager(Controller controller, string startingUrl)
{
_controller = controller;
var settings = new CefSettings { RemoteDebuggingPort = 9515 };
Cef.Initialize(settings);
// Input browser
inputBrowser = new ChromiumWebBrowser(startingUrl);
var obj = new XPathHelper(this);
inputBrowser.RegisterJsObject("bound", obj); //Standard object registration
inputBrowser.FrameLoadEnd += obj.OnFrameLoadEnd;
// Output browser
var browserSettings = new BrowserSettings();
var requestContextSettings = new RequestContextSettings { CachePath = "" };
var requestContext = new RequestContext(requestContextSettings);
outputBrowser = new ChromiumWebBrowser(startingUrl);
outputBrowser.RequestContext = requestContext;
outputBrowser.AddressChanged += InitializeOutputBrowser;
outputBrowser.Enabled = false;
outputBrowser.Name = "outputBrowser";
}
The selenium part:
public class SeleniumHelper
{
public SeleniumHelper()
{
DoWorkAsync();
}
private Task DoWorkAsync()
{
Task.Run(() =>
{
string chromeDriverDir = #"ActionRecorder\bin\x64\Debug\Drivers";
var chromeDriverService = ChromeDriverService.CreateDefaultService(chromeDriverDir);
chromeDriverService.HideCommandPromptWindow = true;
ChromeOptions options = new ChromeOptions();
options.BinaryLocation = #"ActionRecorder\bin\x64\Debug\ActionRecorder.exe";
options.DebuggerAddress = "127.0.0.1:9515";
options.AddArguments("--enable-logging");
using (IWebDriver driver = new OpenQA.Selenium.Chrome.ChromeDriver(chromeDriverService, options))
{
driver.Navigate().GoToUrl("http://www.google.com");
var query = driver.FindElement(By.Name("q"));
query.SendKeys("A google search test");
query.Submit();
}
});
return null;
}
}
And finally, a screenshot for some visualization:
Some help with the issue would be very much appreciated. If i missed some crucial info, feel free to ask for it. Thanks in advance!
Greetz,
Tybs
The behavior is correct. You have one debug address and you can only have one debug address for CEF. Which means when you use Selenium it is only seeing one browser.
By default Selenium will send an command to current active Tab or Window. Now in your case you have multiple Chrome view embedded, but they are technically Chrome Tab/Windows which you have placed on the same form.
So if you are in luck below code in should be able to move you to the Window you are interested in
driver.SwitchTo().Window(driver.WindowHandles.Last());
See if it works. If it doesn't then your only other workaround would be to change the order of Adding ChromiumWebBrowser and that should reverse the window it works on.
Below are some important threads that you should read from top to bottom. Very relevant to your issue/request
https://code.google.com/archive/p/chromiumembedded/issues/421
https://github.com/cefsharp/CefSharp/issues/1076
I'm trying to automate a simple search using selenium webdriver. My code is to launch the google.co.uk page in IE, wait until the search box has appeared, locate the search box and input "compare the market". However I keep getting a NoSuchElementException from the application, even though I can see it on the page.
My code:
class Program
{
static void Main(string[] args)
{
string searchEngine = "www.google.co.uk";
IWebDriver IEbrowser = new InternetExplorerDriver(#"C:\Drivers");
IEbrowser.Url = searchEngine;
WebDriverWait wait = new WebDriverWait(IEbrowser, TimeSpan.FromSeconds(25));
IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
{
return d.FindElement(By.Name("q"));
});
var searchBox = IEbrowser.FindElement(By.Id("lst-ib"));
searchBox.SendKeys("compare the market");
}
}
Error Message:
An exception of type 'OpenQA.Selenium.NoSuchElementException' occurred in WebDriver.dll but was not handled in user code
Additional information: Unable to find element with name == q
HTML info of the search box:
I get the same error message if I try to use any of the other page element locators like Id. But this only appears to error out using the google search page.
You've kinda overengineered this task. :) The code below works fine.
string searchEngine = "www.google.co.uk";
IWebDriver IEbrowser = InternetExplorerDriver(#"C:\Drivers");
IEbrowser.Navigate().GoToUrl(searchEngine);
IEbrowser.FindElement(By.Id("lst-ib")).SendKeys("compare the market");
If you want to wait for an element, there is a simpler way to do this using ExpectedConditions. See an example below. Read the linked docs to see the other available conditions that can be used.
WebDriverWait wait = new WebDriverWait(IEbrowser, TimeSpan.FromSeconds(25));
wait.Until(ExpectedConditions.ElementExists(By.Name("q")));
Following this article
http://www.codeproject.com/Articles/141842/Automate-your-UI-using-Microsoft-Automation-Framew
I'm trying to open an application and press a button. This is all that I want.
public RecordProgram()
{
ProcessStartInfo psi = new ProcessStartInfo(#"C:\MouseController.exe", #"C:\test1.mcd");
psi.UseShellExecute = false;
_calculatorProcess = Process.Start(psi);
int ct = 0;
do
{
_calculatorAutomationElement = AutomationElement.RootElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "MouseController (1,0x)"));
++ct;
Thread.Sleep(100);
}
while (_calculatorAutomationElement == null && ct < 50);
if (_calculatorAutomationElement == null)
{
throw new InvalidOperationException("Calculator must be running");
}
_resultTextBoxAutomationElement = _calculatorAutomationElement.FindFirst(TreeScope.Element, new PropertyCondition(AutomationElement.AutomationIdProperty, "920388"));
if (_resultTextBoxAutomationElement == null)
{
throw new InvalidOperationException("Could not find result box");
}
GetInvokePattern(GetFunctionButton(Functions.Clear)).Invoke();
}
The prograns run and open the executable with my file load But _resultTextBoxAutomationElement returns null value.
_resultTextBoxAutomationElement = _calculatorAutomationElement.FindFirst(TreeScope.Element, new PropertyCondition(AutomationElement.AutomationIdProperty, "920388"));
Shouldn't the call to _calculatorAutomationElement.FindFirst() be passing in TreeScope.Children instead of TreeScope.Element? (Assuming the button element you're after is a direct child of the app window element.) By passing in TreeScope.Element as you are doing, UIA will only look at the _calculatorAutomationElement itself for an element with an AutomationId of 920388.
Thanks,
Guy
To illustrate my comment above which mentioned the Run dlg's Browse button as an example of accessing a Win32 button through its AutomationId, I've just written the code below to access the Browse button. The code is using a managed wrapper around the Windows UIA API, that I'd generated using the tlbimp.exe tool, but I expect taking a similar approach with the .NET UIA API would work fine too.
So for the MouseController UI shown above, try changing the line to...
_resultTextBoxAutomationElement = _calculatorAutomationElement.FindFirst(
TreeScope.Children, new PropertyCondition
(AutomationElement.AutomationIdProperty, "2296138"));
(I'm assuming that the Inspect SDK tool does show the AutomationId of the "start playback" button is "2296138".)
Thanks,
Guy
IUIAutomation uiAutomation = new CUIAutomation();
IUIAutomationElement rootElement = uiAutomation.GetRootElement();
int propertyIdName = 30005; // UIA_NamePropertyId
// First find the Run dlg, which is a direct child of the root element.
// For this test, assume there's only one element whose title is "Run"
// beneath the root. Note! This only works in English UI.
IUIAutomationCondition conditionName =
uiAutomation.CreatePropertyCondition(
propertyIdName, "Run");
IUIAutomationElement wndElement = rootElement.FindFirst(
TreeScope.TreeScope_Children, conditionName);
if (wndElement != null)
{
// Ok, we have the Run dialog. Now find the Browse button through its AutomationId.
int propertyAutomationId = 30011; // UIA_AutomationIdPropertyId
// Using the Inspect SDK tool, I could see that the AutomationId of
// the Browse button is "12288".
IUIAutomationCondition conditionAutomationId =
uiAutomation.CreatePropertyCondition(
propertyAutomationId, "12288");
// Get the name of the button cached when we find the button, so that
// we don't have to make a cross-process call later to get the name.
IUIAutomationCacheRequest cacheRequestName = uiAutomation.CreateCacheRequest();
cacheRequestName.AddProperty(propertyIdName);
IUIAutomationElement btnElement = wndElement.FindFirstBuildCache(
TreeScope.TreeScope_Children, conditionAutomationId, cacheRequestName);
if (btnElement != null)
{
// Let's see the name now...
MessageBox.Show(btnElement.CachedName);
}
}
I have a context sensitive menu that needs text to be hightlighted in order for it to work. However, I'm having problems with selecting the text using Selenium. I start by finding the WebElement I'm looking for, before trying to interact with it using the different mouse events available.
When I'm trying to select parts of the text, it doesn't appear to do anything other than placing the marker at the end of the string.
This is what my textbox looks like:
This is what I need it to look like, or in other words, what I need Selenium to select (Just did it manually for the purpose of illustration:
This is along the lines of what I'm trying to do in code:
public static async Task HighlightElementByCssSelector(this RemoteWebDriver #this, string cssSelector, TimeSpan? timeout = null, TimeSpan? interval = null)
{
var element = await #this.FindElementByCssSelectorAsync(".testmarker-registryentryedit .testmarker-title-field");
Actions action = new Actions(#this).MoveToElement(element).ClickAndHold(element).MoveByOffset(10,0).Release();
action.Build().Perform();
}
#this represents the Driver in this case, and the FindElementByCssSelectorAsync being part of a 'wrapper-framework'.
I've tried different combinations of MoveToElement, DragAndDrop, ClickAndHold etc, but I just can't get it to work. Any pointers as to what might be wrong here?
According to what I understood about your problem I tried to solve it on my local machine (first day of vacation, lol). Sorry, I don't have VS on that machine so I wrote it in Java. The code should be self-explanatory:
#org.junit.Test
public void doTest(){
String query = "This is a test";
WebDriver driver = new FirefoxDriver();
driver.get("https://www.google.com");
WebElement searchBox = new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.id("lst-ib")));
searchBox.sendKeys(query);
// make sure it has focus
searchBox.click();
Actions actions = new Actions(driver);
// go to the beginning of input
actions.sendKeys(Keys.HOME).build().perform();
int length = query.substring(0, query.indexOf("a")).length();
actions.keyDown(Keys.LEFT_SHIFT);
for (int i = 0; i < length; i++){
actions.sendKeys(Keys.ARROW_RIGHT);
}
actions.keyUp(Keys.LEFT_SHIFT);
actions.build().perform();
}
Results in:
Is this what you wanted?