I have a, what seems to be, rather common scenario I'm trying to work through.
I have a site that accepts input through two different text fields. If the input is malformed or invalid, I receive a Javascript pop-up notification.
I will not always receive one, but I should in the event of (like I said earlier) malformed data, or when a search result couldn't be found.
How can I detect this in WatiN?
A quick Google search produced results that show how to click through them, but I'm curious as to whether or not I can detect when I get one?
In case anyone is wondering, I'm using WatiN to do some screen scraping for me, rather than integration testing :)
Thanks in advance!
Ian
Here's what I came up with.
I read this question several times before I came up with the obvious solution..
Can I read JavaScript alert box with WatiN?
This is the code I came up with.. While it does force a delay of 3 seconds if the alert doesn't happen, it works perfectly for my scenario.
Hope someone else finds this useful..
frame.Button(Find.ByName("go")).ClickNoWait();
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
while (stopwatch.Elapsed.TotalMilliseconds < 3000d)
{
if (alertDialogHandler.Exists())
{
// Do whatever I want to do when there is an alert box.
alertDialogHandler.OKButton.Click();
break;
}
}
Related
I'm writing a test using Playwright with C# bindings, and I came across a problem with waiting for element input to have no text.
Before "add" action, input fields look like this:
Article Number input has id="Number", and Name has id="Name" - just to be clear.
After "add" action, input fields are cleared of text:
it's a matter of split second for inputs to be cleared of text, but Playwright doesn't wait for it and starts typing before clearing inputs, which messes up my test.
I've tried to use:
await page.WaitForSelectorAsync("#Number >> text=");
await page.WaitForSelectorAsync("#Name>> text=");
but it didn't help out.
How to wait for text to be empty?
I think your selector is asking Playwright to find an Element with no text. Input Elements store their contents in their Value attribute, so actually always have no text!
You can use this method to check an Input Elements value against a page object, or this method against an IElementHandle.
Maybe have a utility method, something like:
string inputValue = "input";
DateTime timeout = DateTime.Now.AddSeconds(5);
while(timeout > DateTime.Now && !string.IsNullOrEmpty(inputValue)){
inputValue = await page.InputValueAsync("#Number");
}
This will wait for the Input Element to have an empty value.
There is some caveats: Text= does check the value attributes on Input elements of type button & submit, as explained here.
Just in case someone else is looking for an answer to the same problem, Page.WaitForFunctionAsync(expression, arg, options) looks like the ideal way to wait for an element to be empty. The nice thing compared to the before mentioned solution is that it requires less code, the waiting is non busy, and there is less communication between client and browser, because the polling (until ready or timeout) happens inside the browser itself.
You can pass it the JavaScript expression (which will be executed in the browser), for example textBox => textBox.value == ''
And in the second parameter you can pass it the element handle of the textBox.
(I didn't try this myself because I'm normally using PlayWright with NodeJS, but I think with these hints you'll get a long way.)
This may not have been available when the question was asked.
You can now do:
await Expect(page.Locator("#Number")).ToHaveValueAsync("");
is it possible to slow the Sendkeys feature down, when I've set that it sends the keys out of a textbox?
So I mean that it takes longer / that there is a delay before sending each letter?
Ive also thought about if it is possible to have to press a key for sending each line.
I prefer the first option. Hope that is even technically possible.
Thank you for reading this
I've got the answer!
I bet the most people don't need help with this, but why shouldn't I publish the answer I found?
Code:
foreach(char uga in rbox.Text)
{
System.Threading.Thread.Sleep(50);
SendKeys.SendWait(uga.ToString());
}
If you got {ENTER} in the Textbox/String, then do this:
{ENTER} has an alternative keyword.
{ENTER} has "~". Writing the {example} keywords in the string will not work!
Just ENTER has this :( And some other keys, but they dont have keywords in these things: {example}
This site did help me!
I wants to apply dynamic wait in ranorex.
To open a webpage I used static wait like this :-
Host.Local.OpenBrowser("http://www.ranorex.com/Documentation/Ranorex/html/M_Ranorex_WebDocument_Navigate_2.htm",
"firefox.exe");
Delay.Seconds(15);
Please provide me a proper solution in details. Waiting for your humble reply.
The easiest way is use the wait for document loaded method. This allows you to set a timeout that is the maximum to wait, but will continue when the element completes it's load. Here is the documentation on it,
http://www.ranorex.com/Documentation/Ranorex/html/M_Ranorex_WebDocument_WaitForDocumentLoaded_1.htm
First of all, you should be more detailed about your issues. Atm you actually don't state any issue and don't even specify the reason for the timeout.
I don't actually see why you would need a timeout there. The next element to be interacted with in your tests will have it's own search timeouts. In my experience I haven't had a need or a reason to have a delay for the browser opening.
If you truelly need a dynamic delay there, here's what you actually should validate.
1) Either select an element that always exists on the webpage when you open the browser or
2) Select the next element to be interacted with and build the delay ontop of either of these 2
Let's say that we have a Input field that we need to add text to after the page has opened. The best idea would be do wait for that element to exists and then continue with the test case.
So, we wait for the element to exist (add the element to the repository):
repo.DomPart.InputElementInfo.WaitForExists(30000);
And then we can continue with the test functionality:
repo.DomPart.InputElement.InnerText = "Test";
What waitForExists does is it waits for 30 seconds (30000 ms) for the element to exists. It it possible to catch an exception from this and add error handleing if the element is not found.
The dynamic functionality has to be added by you. In ranorex at one point you will always run into a timeout. It might be a specified delay, it might be the timeout for a repo element, etc. The "dynamic" functionality is mostly yours to do.
If this is not the answer you were looking for, please speicify the reason for the delay and i'll try to answer your specific issue more accurately.
Let's assume that some action is performed when I click the button on a web-page. Let's say it takes X seconds and during these seconds a div is displayed in the center of the page. When action processing is finished the div is removed and focus goes to element E.
1) I've written a test in Selenium ( C# ):
stopwatch.Restart();
button.Click();
while (driver.FindElementsById(PopupDivId).Count != 0)
{
Thread.Sleep(10);
}
stopwatch.Stop();
2 ) And a test in javascript (inside my page). Simplified code:
OnClick button handler:
console.time('test');
GotFocus handler on textbox (element E):
console.log(document.getElementById('My_PopupDivId')); // just to be sure - it returns null
console.timeEnd('test');
For some reason Selenium measurements are ~2x bigger than direct javascript measurements.
(400ms vs 800ms).
Is this something wrong with my code or it's just Selenium inaccuracy ( does it actually make sense to measure such things as javascript/DOM performance using Selenium?)
John Koerner's comment is right on the money. You are comparing apples and oranges. Here are some factors affecting the difference:
Selenium uses a wire protocol to talk to your browser. It has to take your parameters, marshal them, send them to the browser, wait for a response, unmarshal the return value and give it to your code. That's in addition to whatever DOM operations are performed.
Your Selenium timing include the click operation as part of what is timed, whereas you start your JavaScript timing inside the event handler for the click. Selenium does some housekeeping work when you ask it to click on a button, like for instance check whether it is visible and bring it in to view if it is not visible. Your Selenium timing includes the cost of this, but your JavaScript timing does not.
Your Selenium code is subject to whatever implicit wait value is set. I don't typically use implicit wait but I've just tested it and found that if I ask Selenium for a list of elements, it will wait until the implicit wait has elapsed before telling me there are none.
To get a better idea of how much Selenium is affecting your results, you should try your test with different delays between the appearance of the div and its removal. I really doubt that a case where your JavaScript timing would yield 2 seconds would translate to a 4 second timing in Selenium.
As for using Selenium for performance measurements, I'd say Selenium is a very blunt tool for such task. When I'm worried about code performance in a browser, I skip Selenium and use JavaScript directly. I have used Selenium to get an idea about performance, in the aggregate. For instance, there's been times I reworked some core part of an application and then ran a test suite that uses Selenium and found the time to run the whole test suite significantly improved. However, as I said, this is blunt. We're talking seconds of difference, not milliseconds.
On this site if you do too many clicks or post comments too fast or something like that you get redirected to the "are you a human" screen. Does anybody know how to do something similar?
It's almost certainly a heuristic that tries to "guess" that a user is some form of automated process, rather than a person, for example:
More than "x" requests to do the same thing in a row
More than "x" actions in a "y" period of time
Ordinarily the "x" and "y" values would be formulated to be ones that it would be unlikely for a "real person" to do, like:
Editing the same answer 5 times in a row
Downvoting 10 questions within 1 minute
Once you've got your set of rules, you can then implement some code that checks them at the start of each request, be it in a method that's called in Page_Load, something in your masterpage, something in the asp.net pipeline, that's the easy bit! ;)
Here is a very nice Captcha Control for asp.net that first of all you need
http://www.codeproject.com/KB/custom-controls/CaptchaControl.aspx
Then you can use it together with this idea that try to find the dos attacks
http://weblogs.asp.net/omarzabir/archive/2007/10/16/prevent-denial-of-service-dos-attacks-in-your-web-application.aspx
be ware of a bug in this code in line if( context.Request.Browser.Crawler ) return false;, its must return true, or totally remove it for sure.
and make it your compination for the clicks, or submits.
If a user make too many clicks on a period of time, or many submits, then you simple open the capthaControl, and if the clicks are by far too many, then triger the dos attact. This way you have 2 solution in one, Dos attact prevent, with captcha at the same time.
I have made somthing similar my self, but I have change the source code of both, a lot to feet my needs.
One more interesting link for a different code for the dos attack.
http://madskristensen.net/post/Block-DoS-attacks-easily-in-ASPNET.aspx
Hope this help you.
At a guess...
Write a HTTP handler that records requests and store them in session.
When a new request comes in, check to see how many requests are stored (and expire old ones).
If the amount of requests in the past few minutes exceeds a given threshold, redirect the user.
If you're doing this in ASP.NET webforms, you could do this check on the site master page, ( or write a IHttpHandler).
If you're using an MVC framework, you could write a base controller that does this check for every action.
With rails, you could write a before_request filter.
With asp.net MVC, you could write a [ActionFilterAttribute] attribute
You should have a session to track the user activity.
In session you can have counter for commenting and posting like:
(pseudo code instead of C#, sorry :)
if (post_event) {
posts_during_1_minute_interval++;
if (time_now-reference_time > 1_minute) {
reference_time = time_now;
posts_during_1_minute_interval=0;
}
}
...
if (posts_during_1_minute_interval > 10) redirect("/are-you-human.htm");
where on are-you-human.htm page you can have recaptcha, as they have here on StcakOverflow.com
see also:https://blog.stackoverflow.com/2009/07/are-you-a-human-being/
just check how many hit / minutes you get from a specific ip or session or whatever and decide what are your preferred threshold and your good to go
I'd also check the user agent header of the request - if it doesn't look like a popular browser (or is empty) then throw the "are you a human?" page.