I am trying to use CssSelector to locate an element on my webpage. I am using Firefox driver.
Here is how I am using the locator (I checked that Selenium IDE is able to locate my element with this
[FindsBy(How = How.CssSelector, Using = "label:contains('Version: 2.0.')")]
public IWebElement labelVersion;
But when use this in the C# code and initialize it with
PageFactory.InitElements in my constructor.
I hit this error... (the error itself is pretty clear but I don't know how to fix it)
Appreciate any inputs.
OPC.Tests.SmokeTest (TestFixtureSetUp): SetUp :
OpenQA.Selenium.InvalidSelectorException : The given selector
css=label:contains('Version: 2.0.') is either invalid or does not
result in a WebElement. The following error occurred: [Exception...
"An invalid or illegal string was specified" code: "12" nsresult:
"0x8053000c (NS_ERROR_DOM_SYNTAX_ERR)" location:
"file:///........../anonymous439571104.webdriver-profile/extensions/fxdriver#googlecode.com/components/driver_component.js
Line: 5811"]
Selenium delegates CSS queries down to the browser. This means that CSS queries need to follow CSS standard.
Unfortunately :contains was removed from the standard a while back. I recommend that you redo your selector with whats available from the spec or use XPATH.
:contains works in Selenium RC because RC uses Sizzle, the selector search library in jQuery if you are wondering why it works in RC and not WebDriver
Related
Using .net 6, bUnit 1.13.5 Mudblazor 6.0.17
I am trying to write unit tests for a razor component that is in a dialog box and bUnit is unable to find any of the components or class/ids in it. I am getting the following error...
Message:
Bunit.ElementNotFoundException : No elements were found that matches the selector '#CancelButton'
in the ColumnTrackerEditDialog.razor there is the following line
<MudButton id="CancelButton" OnClick="#Cancel">Cancel</MudButton>
This should always be rendered and it not under any conditional statements. The unit test for this is as follows (so far)
[Test]
public async Task ColumnTrackerEditDialogUITest_CancelButton()
{
var item = GetColumnTrackerPeco();
PopulateData(item);
var page = TestContext!.RenderComponent<ColumnTrackerEditDialog>(parameters =>
parameters.Add(p => p.Item, item));
Assert.IsNotNull(page);
var cancelButton = page.Find("#CancelButton");
Assert.IsNotNull(cancelButton);
cancelButton.Click();
}
The test set up is fine as the page is not null and on non dialog pages I can find elements by ids, classes or components.
Is this an issue because it's a dialog or am I missing something else?
I have tried to find "button", ".mud-button" and other classes, as well as .FindComponent and other tags within the component and it's not finding anything.
Is the component being added asynchronously? If that's the case, try using cut.WaitForElement("#CancelButton") instead.
Another approach is to stub out the MudBlazor component, so it's not directly influences your test, and instead find the stub and assert you passed the expected parameters to it. Learn more here: https://bunit.dev/docs/providing-input/substituting-components
I'm creating a test automation framework in C# .Net using Appium to automate IOS and Android and wanted to use Page Object Design Pattern. So I wanted to utilize the PageFactory extension.
By adding the DotNetSeleniumExtras.PageObjects.Core as NuGet package results in an error (red squiggly lines). 4 errors
CS7069: Reference to type 'IFindsById" claims it is defined in 'WebDriver', but it could not be found.
I needed this extension DotNetSeleniumExtras.PageObjects.Core in order for me to instantiate the Page objects and be able to implement the Page Object Design pattern.
Please let me know if I'm missing something here or if there are any workarounds. Thanks in advance!
Below is my code for added context:
using NUnit.Framework;
using OpenQA.Selenium.Appium.iOS;
using OpenQA.Selenium.Appium.PageObjects;
using SeleniumExtras.PageObjects;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
namespace NativeApp_TestAutomation.Tests.Specs.IOS
{
[TestFixture]
public class LoginTest
{
private IOSDriver<IOSElement> _driver;
private HomeScreen _pageObject;
[OneTimeSetUp]
public void BeforeAll()
{
var capabilities = Capabilities.GetIOSCapabilities("");
var serverUri = Env.ServerIsRemote() ? AppiumServer.RemoteServerUri : AppiumServer.LocalServiceUri;
_driver = new IOSDriver<IOSElement>(serverUri, capabilities, Env.LaunchTimeoutSeconds);
var timeSpan = new TimeOutDuration(new TimeSpan(0, 0, 0, 5, 0));
_pageObject = new HomeScreen(_driver);
PageFactory.InitElements(_driver, _pageObject, new AppiumPageObjectMemberDecorator(timeSpan));
}
}
}
I'm getting the red squiggly lines here with all having the same errors.
One of the most common reasons for that is a mixture of version and assemblies because of different versions and their compatibility.
If you can try following steps the issues most likely would be solved:
Appium.net latest come out with dependency on DotNetSeleniumExtras.PageObjects v3.11.0 and WebDriver 3.141.0
DotNetSeleniumExtras.Core of v3.12.0 (do not use latest, target v3.12.0) come out with dependency on WebDriver 3.12.0
DotNetSeleniumExtras.PageObjects v3.11.0 rely on WebDriver 3.11.0
So by adding WebDriver 3.12.0 version conflict should be fixed.
This one is a simplest approach - if previous version have enough features then It's done and you can just wait for updates.
The second option that can help you is a binding redirects. The idea is pretty simple, you need to ensure that app know where your WebDriver and it is of correct version.
One good explanation is here (but believe me this is the last thing you want to do, fixed in one place become broken in another) Adding a bindingRedirect to a .Net Standard library
I'm moving from a Java environment to .NET and need to write Webdriver tests using a page object model.
In Java I would use the following annotation:
#FindBy(linkText = "More details")
WebElement moreDetailsButton;
Please would someone be able to tell me how to define a WebElement using C#? Also, is the PageFactory.initElements used the same way?
Thanks
Steve
Yes, there is a direct translation.
You are looking for FindsBy:
[FindsBy(How = How.LinkText, Using = "More details")]
private IWebElement moreDetailsButton;
As for the PageFactory.initElements, yes, it's a very similar thing in .NET, usually called in the constructor of the Page Object:
public class LoginPage
{
private IWebDriver _driver;
public LoginPage(IWebDriver driver)
{
_driver = driver;
PageFactory.InitElements(_driver);
}
}
Note, that the Selenium project is entirely open source. You can easily see the source the Page Objects 'helper' classes here.
I'm using Selenium's IWebDriver to write Unit Tests in C#.
Such is an example:
IWebDriver defaultDriver = new InternetExplorerDriver();
var ddl = driver.FindElements(By.TagName("select"));
The last line retrieves the select HTML element wrapped in a IWebElement.
I need a way to simulate selection to a specific option in that select list but I can't figure out how to do it.
Upon some research, I found examples where people are using the ISelenium DefaultSelenium class to accomplish the following, but I am not making use of this class because I'm doing everything with IWebDriver and INavigation (from defaultDriver.Navigate()).
I also noticed that ISelenium DefaultSelenium contains a ton of other methods that aren't available in the concrete implementations of IWebDriver.
So is there any way I can use IWebDriver and INavigation in conjunction with ISelenium DefaultSelenium ?
As ZloiAdun mentions, there is a lovely new Select class in the OpenQA.Selenium.Support.UI namespace. That's one of the best ways to access a selection element and it's options because it's api is so easy. Let's say you've got a web page that looks something like this
<!DOCTYPE html>
<head>
<title>Disposable Page</title>
</head>
<body >
<select id="select">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</body>
</html>
You're code to access the select would look like this. Note how I create the Select object by passing a normal IWebElement to it's constructor. You have plenty of methods on the Select object. Take a look at the source for more information, until it gets properly documented.
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium;
using System.Collections.Generic;
using OpenQA.Selenium.IE;
namespace Selenium2
{
class SelectExample
{
public static void Main(string[] args)
{
IWebDriver driver = new InternetExplorerDriver();
driver.Navigate().GoToUrl("www.example.com");
//note how here's i'm passing in a normal IWebElement to the Select
// constructor
Select select = new Select(driver.FindElement(By.Id("select")));
IList<IWebElement> options = select.GetOptions();
foreach (IWebElement option in options)
{
System.Console.WriteLine(option.Text);
}
select.SelectByValue("audi");
//This is only here so you have time to read the output and
System.Console.ReadLine();
driver.Quit();
}
}
}
A couple things to note about the Support class however. Even if you downloaded the latest beta, the support DLL won't be there. The Support package has a relatively long history in the Java libraries (that's where PageObject lives) but it's still pretty fresh in the .Net driver. Fortunately, it's really easy to build from source. I pulled from SVN then referenced the WebDriver.Common.dll from the beta download and built in C# Express 2008. This class hasn't been as well tested as some of the other classes, but my example worked in Internet Explorer and Firefox.
There's a few other things that I should point out based on your code above. Firstly the line you were using to find the select element
driver.FindElements(By.TagName("select"));
is going to find all select elements. you should probably use driver.FindElement, without the 's'.
Also, very rarely would you use INavigation directly. You'll do most of your navigation like driver.Navigate().GoToUrl("http://example.com");
Lastly, DefaultSelenium is the way to access the older Selenium 1.x apis. Selenium 2 is a pretty significant departure from Selenium 1, so unless you're trying to migrate old tests to the new Selenium 2 api (often referred to as the WebDriver api) you won't use DefaultSelenium.
You should get all option elements from your select using ddl.FindElements(By.TagName("option"));. Then you can iterate through the returned collection and select required item(s) by using SetSelected method of the IWebElement
Update: It seems that there's now a C# implementation of the Select in WebDriver - previously it was in Java only. Please take a look at its code and it is easier to use this class
Recently, my team converted ASP.NET project from .NET 1.1 to .NET 2.0. Everything is pretty good so far except for one web page.
This is the error message I got when I tried to open this page:
Server Error in '/' Application.
Parser Error Description: An error
occurred during the parsing of a
resource required to service this
request. Please review the following
specific parse error details and
modify your source file appropriately.
Parser Error Message: Ambiguous match
found.
Source Error:
Line 1: <%# Control Language="c#"
AutoEventWireup="false"
Codebehind="Template.ascx.cs"
Inherits="eReq.Web.WebControls.Template.Template"
TargetSchema="http://schemas.microsoft.com/intellisense/ie5"
%> Line 2: Line 3:
function
ExpandCollapse_Template(inBtn,
inSection, inSectionID) {
Source File:
/WebControls/Template/Template.ascx
Line: 1
-------------------------------------------------------------------------------- Version Information: Microsoft .NET
Framework Version:2.0.50727.3053;
ASP.NET Version:2.0.50727.3053
I tried renaming class and renaming filename but it didn't work.
Anyone have any idea on this?
It may appeared because of different names of components? for example Button1 and button1, it compiles as casesensitive, but executed as caseinsensitive.
In your ASCX file, go through each and every control and change its id. For example,
<asp:TextBox id="foo" />
change it to
<asp:TextBox id="foo1" >
You've probably got a control with an ID that matches a property in your ascx file, so when the compiler is trying to make instance variables its colliding.
I've the same problem and it solved and the solution is in check your code behind and you will find a couple of Controls with the same name:
protected Button Home;
protected System.Web.UI.HtmlControls.HtmlAnchor home;
you have to erase one line or comment it.
The selected answer seems to be the right one.
In my case i found that im using a variable in the codebehind with the same name as a control in the aspx file, just with different case usage.
I'd trawl your web.config for 1.1 and 2.0 references to the same DLL. In most cases that I have gotten this it was System.Web.Extensions.
Also check the #registers in Pages if that fails.
Good luck (it is not a fun bug to find!)
Dan
Same Name Id in aspx file and property inside aspx.cs file
when .aspx page and behind aspx.cs class contains Same property this kind of problem occur. When I am searching the solution for this problem.. not found any useful content. finally I solved the problem by renaming private property name to different inside aspx.cs class attached image as screenshot.
if anyone still facing the problem you may try
Screenshot 1
Screenshot 2
This is due to what can only be described as a defect in System.Web.UI.Util.GetNonPrivateFieldType(Type classType, String fieldName) that allows UI (.aspx/.ascx) fields to compile as case-insensitive but attempts to retrieve them as case-sensitive during the intial parse.
A potential remedy for the time being is to catch it at compile-time with an ms-build task.