Extending Selenium: How to call commands? - selenium

I read about user extensions and extending selenium but am wondering how to call a command from within a custom command I'm creating.
I added a file similar to the following to Selenium core extensions (user-extensions.js) in Selenium IDE Options.
// selenium-action-example.js
Selenium.prototype.doExample = function() {
this.doOpen("/"); // doesn't waitForPageToLoad like the command does
// These two commands are equivalent to the clickAndWait command. NOT!
// For proof, see the filterForRemoteControl function:
// http://code.google.com/p/selenium/source/browse/trunk/ide/src/extension/content/formats/formatCommandOnlyAdapter.js?r=8284#68
this.doClick("css=a#example");
this.doWaitForPageToLoad(); // doesn't wait at all
this.doClick("link=Example");
this.doWaitForElementPresent("example"); // error! undefined function
this.doClick("example");
};
In other words, how can I wait for things between clicks within a custom action?

Your command
this.doWaitForPageToLoad(); // doesn't wait at all
Doesn't wait as you have not specified wait time in brackets. You should write it as
this.doWaitForPageToLoad(30000); // time in milliseconds
Tour another Command
this.doWaitForElementPresent("example"); // error! undefined function
as no function is there in Selenium. whenever it waits for an element it checks that element is present or not so you should wait for time until it is visible/present.
Using For loop and ispresent commands you can do it.
Regards

Waiting for an page load does not to work in current versions of Selenium. As far as I can see, this is because the doWaitForPageToLoad defers the waiting until the end of the current Selenium IDE command, i.e. waiting for a page load stops the test execution until the page has loaded, but not the execution of the actual javascript function that this was executed in.
You will have to split your function in two at this point.

Related

how can i check if an element visible without stopping the program from running in cypress?

When I try to look for an element in the software I am working on and it is not found the automation stops.
What can I do so that if the element is not found the automation will continue to run?
There are multiple solutions out there for Cypress. As a quick solution, you can set a cookie value and decide to skip the particular test. add this code to your cypress/support/index.js
afterEach(function onAfterEach() {
if (this.currentTest.state === ‘failed’) {
cy.setCookie(‘shouldSkip’, ‘true’);
//set cookie to skip tests for further specs
Cypress.runner.stop();
//this will skip tests only for current spec
}
});
You can read more and see the full blog post here:
Skipping Cypress tests on first failure

Restart fixture when it fails

I wrote a test that passes 95% of the time, failing the other 5%. I still don't know why it fails (my guess is that components are not rendered correctly).
I implemented a page reload call to reload the page and try again, but it's not very reliable.
What's the best way to restart the fixture in case it fails?
Here's a sample test that intentionally fails to emulate my selector that works most of the time, but fails sometimes.
import { Selector } from 'testcafe';
const URL = 'https://www.youtube.com/watch?v=RWQtB6Xv01Q';
fixture `Portal Experience playback`
.page `${URL}`;
test('Testing YouTube', async t => {
await t.click(Selector('.wrong-selector')); // to emulate my unstable test
});
Results in
✖ Testing YouTube
1) The specified selector does not match any element in the DOM tree.
Is it possible to put the test in a for loop and have it break out of the loop in case the test passes?
The quarantine mode serves this purpose. In this mode, TestCafe will restart a failed test again until it passes or fails 3 times and will consider it failed only if it fails 3 times. Get more details about the quarantine mode in this article: Quarantine Mode.

Selenium - watch for an error condition AND run 'happy path' test code

My app displays an error dialog whenever a JavaScript error occurs. This is always a bad sign, so I want to set up my tests so that, if the error dialog appears, it causes the test to fail there and then.
So I'd like to do something like (very much pseudocode!);
// start a new 'guard' thread;
start {
found = this.driver.wait(untilVisible(By.css('.myErrorDialog')), VERY_LONG_TIMEOUT);
if (found) {
// the error dialog appeared! That's bad!
throw();
}
}
// now run the test
login();
clickButton();
testBannerContains();
But I'm having trouble and I think it has to do with the way Selenium schedules actions.
What I've found is that for a single driver, I can only schedule one thing at a time, so the guard I set up early in the test blocks the body of the test from starting.
Is there a better way to handle conditions like 'this should never happen', or a way to create two independent threads in the same test?
So the problem with the code you have is that it immediately runs it and waits for a VERY_LONG_TIMEOUT amount of time for that error dialog to appear. Since it never does, it continues to wait. You have already discovered that is not what you want... ;)
I haven't done anything like this but I think you want a JS event handler that watches for the event that is triggered when the error dialog appears. See the link below for some guidance there.
Can my WebDriver script catch a event from the webpage?
One option would be to watch for that event to fire and then store true (or whatever) in some JS variable. Before leaving a page, check to see if the variable is set to true and if so, fail the test. You can set and get JS variables using JavascriptExecutor. Some google searches should get you all you need to use it.

Stop the selenium server until File uploaded

I am using a file upload task with Selenium.
The problem here is, to upload file, it is taking 5-10 seconds time. But i have to stop the Selenium server until it uploaded completely.
Here is some example code.
selenium.type("id=Fileuploader","c:\\mypic.jpg");
selenium.click("id=submmit");
It is giving error because the selenium.click statement is executing right after the selenium.type statement without waiting for the file to upload fully.
So, what should I use here to stop the Selenium server (server has to wait for sometime)?
Asynchronous requests are always hard to track. There must be some change on the page when the file is uploaded, so look for it, wait for it.
You can try waitForCondition().
Or some sort of isElementPresent() magic
final int TIMEOUT = 10000; // ten seconds
long targetTime = System.currentTimeInMillis() + TIMEOUT;
while((System.currentTimeInMillis() < targetTime)) {
if (selenium.isElementPresent("xpath=something")) {
break;
}
}
EDIT: If there's no new element, there has to be at least some sort of change. For example, if your asynchronous upload changes a value of some hidden input element, you could test for it using getValue(), or maybe just a smart locator:
isElementPresent("xpath=//input[#type='hidden' and contains(#value,'mypic.jpg')]");
EDIT2: If the element for which we check (in this case, picture preview) is present even before the upload, then it was just not visible and we can test that by isVisible()
If worst, you can always use some Thread.sleep() in the code. But the best way is to see the advanced usage - explicit and implicit waiting
After uploading the file, new element is coming which showing the preview of the uploaded element.
So, i used
selenium.isVisible("xpath of new preview element")
Put it in loop. It will work.
Thank you.

Can I use captureScreenshotOnFailure to capture an error not only the failure in selenium RC?

I'm trying to capture the screen whenever something goes wrong, either an error or failure
You can use selenium.captureScreenshot() create a util method which you can call whenever you want to capture the screen shot. However if you are using Testng then you can refer http://satishjohn.wordpress.com/2012/06/04/selenium-testng-error-screenshot-listene/ but this is for failedtest passedtest skipped test. however you can put the capturescreen shot as a helper method in you utilities and call it under the testng method.