I am developing on a program in C# that automates inputting information into a website. This program uses a library (Coypu) that allows this and for the execution of Javascript to manipulate further.
The problem comes in two forms:
The website only uses names (not ids) for its objects and I must use IE8 for them. Therefore I cannot use document.getElementsByName('name'); because it's not supported in earlier versions of IE.
I found a workaround by utilizing the form that's on the site but am having trouble using it because the site has to click a link to create a second tab for itself, leaving me helpless in grabbing the form in the second tab. Using something like document.forms[formIndex].elements['elementsName']; (although the tab appears to have focus) only gives me the forms from the main tab.
Has anyone ever fixed this problem or found a workaround in Javascript? Also, I'm not sure if jQuery can be used in my scenario as the Javascript is a string passed in to a C# method. However, it may or may not work.
If the website you are testing has access to jQuery you can use Coypu to populate specific fields in their respective forms:
e.g.
void PopulateInputField(int formName, string fieldName, string fieldValue)
{
browser.ExecuteScript(string.Format("$('form[name='{0}'] > input[name='{1}']).val('{2}')", formName, fieldName, fieldIndex));
}
Note how the C# string passed to Coypu's ExecuteScript contains the jQuery.
Related
Please this simple scenario:
#Chrome
Scenario: Simple Calculation
Given user
When User login to the system
And ....
So i have many scenarios, each scenario use default Browser or specific one (in this example the Browser is Chrome)
So i have several URLs than i am checking so i looking for way to define global Tag what will represent URL and inside .cs file this Tag will converted into my URL (and as i mentioned before i have several).
And i want to use it this way:
#GlobalURL
#Chrome
Scenario: Simple Calculation
Given user
When User login to the 'GlobalURL'
And ....
Any suggestion ?
If you want to use #GlobalURL tag for scenarios, then you can add method with annotation: [BeforeScenario] and in this method get that hook, and depending on it's value get correct url. In my project I made a separate class - TestConfiguration, which properties (base url, key, what kind of test) and filled from tags before every scenario, and then used in test.
Also you can in scenario send parameter and based on it choose url in the code.
In my effort of trying to find a neat way to validate which buttons are visible to the user based on his Role and Permissions i have encountered a problem. I am using the Page Object Model design pattern with selenium to test a website. A few pages have a different set of buttons which should either be visible or not to the user according to his role.
I keep a Dictionary<Permission,IWebElement> and initialize it in the constructor of the page (class representing a certain page in the site).
All web elements are defined as follows:
private IWebElement btn_openShop => driver.ById("open_shop");
(ById is equivalent to FindsElement(By.Id("open_shop"))
The problem is that if the button shouldn't exist an exception is thrown when adding it to the Dictionary.
Note: moving the initialization of the Dictionary wont help since i test both cases (one in which the user should see the button and one in which he shouldn't).
I changed the Dictionary to be of type <Permission,Lazy<IWebElement>>
and added items to it as follows:
dictionary.Add(somePermission,new Lazy<IWebElement>(()=>the button))
Edit: this technique works but it seems that when debugging in visual studio the code crashes.
Any thoughts? (no exceptions are thrown during test execution).
I'm very new to Selenium RC. I'm using .NET (though I don't think it is relevant), I have opened a page, but I want to confirm that the page was actually opened. I have a few ideas like using .Select() or using one of the .get*() methods, but I want to do what is considered the best practice by others in the Selenium community.
I usually assert some text or element on the page. You most likely don't just want to make sure the page "loaded" you want to make sure it loaded something specific
I am currently confirming the page was returned using the following:
[Then(#"the (.*) page should be displayed")]
public void ThenThePageShouldBeDisplayed(string pageName) {
Assert.IsTrue(selenium.GetLocation().Contains(pageName));
}
This happens to be a SpecFlow test step implementation.
My typical application has a couple of textboxes, checkbuttons, radiobuttons, and so. I always want to load the settings the user used the last time when the program starts, and also want to save the settings as the users clicks "Save settings" or closes the application. When the user attempts to save the settings, I'll have to check each of the controls for input errors (sometimes they have to have a max length, other times only caps, other times other things, there isn't a rule for them all, everytime it'll be different), and only if everything's OK i'll let him save the options. If there is something wrong, no option is saved and my errorcontrol provider will pop up a description of the input type info that should be put in that control.
I've been designing this from scratch for all my projects, but it's being a pain to do it. So I'd thought maybe now was the time to do some library to help me. I thought initially that maybe it'd be a good idea to have all the controls on my form that are going to be part of this save/load process to have an attribute associated with them, something like this
public delegate bool InputIsOkHandler();
public class OptionsAttribute : Attribute {
public Control controlRef;
public InputIsOkHandler IsInputOk;
public string errorMessageToShowOnErrorProvider;
public OptionsAttribute(Control controlRef, InputIsOkHandler inputHandler, string errMessage) {
...
}
}
The main problem here is that when I declare the attribute on a given var:
[Options(...)]
TextBox textBox1 = new TextBox();
I'll get
Error 1 An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type.
So I guess this approach isn't the best one. What would you guys do in this situation? Would you use attributes? Would you use other mechanisms?
Thanks
Do you know that .NET already includes such a system since 2.0? See MSDN, CodeProject and this white paper from WestWind.
The Personalization and User Profiles supported in ASP.NET 2.0 can be a nice way to achieve your goal.
You can check this MSDN article for a overview Personalization in ASP.NET 2.0
In our new product we have a few data entry fields that require you to search for the correct value to place in this field.
When you enter this data entry field I would like to provide a search option via something on the view (perhaps an Ajax implementation) and have it allow searching of the database for the value, but when the result returns I want to keep the existing values in place for other fields not affected by the search.
But I have no idea how to do this with MVC. Does anyone have any suggestions on how this should be done?
Write your data entry page in the
usual way for an ASP.NET MVC view.
Get it working without the Ajax
(e.g., submit works correctly when
you just type in the values, without
auto complete).
Write the prototype for a JavaScript method you'll called when the user performs a certain action (e.g. presses a key inside of a certain control). But this inside a script tag in your aspx page. Unfortunately, stack overflow seems to "sanitize" script tags in my example, so I can't demonstrate that part. But you're JavaScript prototype will look something like this:
function startAutoComplete() {
}
Now hook up the event handlers on the user interface control. You need to call the function you've just prototyped an appropriate event handlers for your application. From your description, it sounds like you might want to use onkeydown, but there are lots of events to choose from. You probably need to handle more than one event, as appropriate for your application.
So far, everything that we've done has been standard aspx and JavaScript. In this step, we'll do the only part of the whole process which is really different for ASP.NET MVC. You need to add an action to your controller which will be called (indirectly) by the JavaScript prototype you've just written. The action should accept appropriate input (e.g., a string representing the text from control, or something like that, as appropriate for your application) and return its results in JSON format. I'm going to show a really simple example here; feel free to substitute more complex code in your real application.
public ActionResult GetSuggestions(string searchText)
{
return Json(new {SearchText = searchText});
}
This example just returns a JavaScript object containing one property, which contains the value passed to the function. Like you said, you can write something more useful for your application.
Now you need to call this function in JavaScript. The URI will look something like:
http://localhost/mycontroller/GetSuggestions?searchText=Foo
It is possible to make Ajax calls without a JavaScript library, but much easier if you use jQuery or some other library which handles cross-browser compatibility issues for you. Since I happen to like jQuery, I'll demonstrate that. Let's update the startAutoComplete method we prototyped earlier:
function startAutoComplete() {
var searchText = $("#myeditorid").text();
$.getJSON("/mycontroller/GetSuggestions?searchText=" + searchText,
null,
autoCompleteResponse);
}
The first line uses jQuery to get the text in the control with the ID myeditorid. We'll pass this to the ASP.NET MVC action as the searchText argument, by appending it as a query string parameter.
The next line, which starts with $.getJSON calls a jQuery function which makes an Ajax call to the URI you specify. We pass an argument, autoCompleteResponse, which is the name of a JavaScript method to be called if the response from the Ajax call is successful. Now we have to write autoCompleteResponse.
function autoCompleteResponse(data) {
if (data.SearchText)
{
$("#myeditorid").text(data.SearchText);
}
}
This says, "If the data returned has a SearchText property, set the text of the control to that value." Again, do whatever is appropriate for your application with the data returned.