I have a Selenium WebDriver based testcase, which pauses during execution. It should upload thousands of files to a website. When it chooses the file to upload it sometimes doesn't click ok, but waits for manual interaction. In most cases it is working perfectly.
I use StringSelection to copy and paste file source to input field.
StringSelection cp = new StringSelection(fileSource);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(cp, null);
I think your test could be running to quickly? If this is the case, then you could potentially use WebDriverWait?? WebDriverWait could be used to wait for the 'OK' element to be visible prior to clicking and therefore proceeding.
I might be wrong, but I can't really tell what the issue is without the rest of the code.
Personally, I use the following method which I can then call
public void waitForElementToBeVisible(String cssSelector) throws Throwable {
try {
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.or(
ExpectedConditions.visibilityOfElementLocated(By.cssSelector(cssSelector))
));
} catch (Exception e) {
System.out.println("Timeout exceeded");
closeDriver();
}
}
For behavior "When it chooses the file to upload it sometimes doesn't click ok, but waits for manual interaction. In most cases it is working perfectly." I prefer use failed retry count. Every step with click should be wrapped up on the test and if test result=failed - retry test some times(3 or 5). JUnit have good mechanizm for that:
#RunWith(Runner.class)
public abstract class AbstractTest extends LibTest {
#Rule
public JUnitRetry retry = new JUnitRetry(3);
}
public class Test extends AbstractTest
#Test
public void testCp(String fileSource){
StringSelection cp = new StringSelection(fileSource);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(cp, null);
}
}
Below code working fine for the similar scenario in our environment.
StringSelection cp = new StringSelection(fileSource);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(cp, null);
Robot robot=new Robot();
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
We can also use AutoIT to perform this type actions.
Please find AutoIT code to handle this case.
Download AutoIT ,write this code in AutoIT name it as 'Loadfromdisk' and compile. .exe will be generated, please place exe somwhere in your local drive(ex: E:\Loadfromdisk.exe)
AutoItSetOption("WinTitleMatchMode","2") ;
$title=WinGetTitle("[CLASS:DirectUIHWND; INSTANCE:2]")
WinActivate($title)
WinWaitActive($title)
If WinExists($title) Then
WinFlash($title,"", 4, 500) ;Just to Flash the window
EndIf
Sleep(1000)
ControlSetText($title, "", "Edit1", fileSource)
Sleep(1000)
ControlClick($title,"","Button1")
Exit
Load from disk Selenium Java code, this will load the file placed at 'filesource' path mentioned in AutoIT code into web application
String strAutoIT = "E:\\Loadfromdisk.exe";
Thread.sleep(3000);
String[] astrArg = null;
astrArg=new String[]{strAutoIT};
Runtime.getRuntime().exec(astrArg);
Please see whether this helps to run your testcase.
Related
Is it not possible to have both SUCCCESS and FAILURE Outcome in the story?
Lifecycle:
After:
Outcome: FAILURE
Given I capture page screenshot
Given I close browser
Outcome: SUCCESS
Given I close browser
Scenario: Sample one
Given I open browser
When I do something
Scenario: Sample two
Given I open browser
When I do another thing
For example, for failures I want to take a screenshot before closing the browser. If successful I just want to close the browser.
I know I can just close the browser at the end of all my scenarios and only have the failure outcome remain. I would like to know if there is a way to do this in the Lifecycle After.
Thanks.
Quoting OP:
For example, for failures I want to take a screenshot before closing the browser. If successful I just want to close the browser.
Now, the interesting question will be which framework are you using for your assertions?
I'll assume you use Junit which comes bundled with JBehave as JBehave relies on knowing there is an error by JUnit's thrown exception.
The idea is to:
a) throw an exception when an error occurs (so need to check on every step)
b) take a screenshot
c) continue with testing (i.e. closing the browser)
So in order to throw an exception, you really do no need to do much as this is done automatically when using JUnit's Assert statement.
so for example
Assert(username.equals("expected_user").isTrue();
If the above fails an exception will be thrown.
You can capture it as such:
public class RunnerExtension implements AfterTestExecutionCallback {
#Override
public void afterTestExecution(ExtensionContext context) throws Exception {
Boolean testResult = context.getExecutionException().isPresent();
System.out.println(testResult); //false - SUCCESS, true - FAILED
}
}
#ExtendWith(RunnerExtension.class)
public abstract class Tests {
}
Taken from this answer:
JUnit5 - How to get test result in AfterTestExecutionCallback
So basically you override the standard behaviour -after- each assertion has been executed. In the case above you can add (when an exception is thrown --> take screenshot).
Here is the take a screenshot code for Selenium-Java:
WebDriver driver = new FirefoxDriver();
driver.get("http://www.google.com/");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// Now you can do whatever you need to do with it, for example copy somewhere
FileUtils.copyFile(scrFile, new File("c:\\tmp\\screenshot.png"));
Hope the above helps!
I have a java class that is used to perform login action using selenium. There are currently 10+ different login types and as such there is a lot of if else involved which looks bad and is not efficient.
Eg:
if (logintype == 1 )
{
driver.findElement(By.id("username")).clear();
driver.findElement(By.id("username")).sendKeys(username);
driver.findElement(By.id("password")).clear();
driver.findElement(By.id("password")).sendKeys(password);
driver.findElement(By.id("signin")).click();
}
else if (logintype ==2 )
{
driver.findElement(By.id("username")).clear();
driver.findElement(By.id("username")).sendKeys(username);
driver.findElement(By.id("password")).clear();
driver.findElement(By.id("password")).sendKeys(password);
driver.findElement(By.id("signin")).click();
}
...........
...........
Other than code not being efficient the new code needs to be written, pushed and the server needs to be restarted every time a new login module is added.
I wanted to see if i can get the logic for login can be stored in db and if it can be compiled at runtime. I found groovy shell but i dont know how to get the results back to my class file. Also running groovy shell would require a lot of code changes. Is it possible in java
public class ExecuteAuth implements Runnable{
private WebDriver driver;
driver = new FirefoxDriver(firefoxBinary, profile, cap);
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.manage().window().maximize();
//MongoDB code
DBCursor dbObjects = loginCollection.find();
while (dbObjects.hasNext()) {
DBObject dbObject = dbObjects.next();
loginModule.add(new LoginModule((BasicDBObject) dbObject));
String loginType = (String) dbObject.get("loginType")
String script;
if (loginType.equals("1")) {
script = (String) dbObject.get("script")
}
}
GroovyShell shell = new GroovyShell ();
shell.evaluate(script);
RUN REST OF THE LOGIN LOGIC AFTER THE CODE IS EVALUATED
}
I strongly advise against that approach. You are opening a door to bad code be injected in your application. Another way could be upload to your server your new jars and take advantage of class loader to load classes at runtime:
How should I load Jars dynamically at runtime?
Also, you have alternatives to avoid if-else's: usage of interfaces and factory methods are the way to go, imho. And put your login's implementations on different classes implementing a Login interface, for example.
Factory method design pattern:
http://www.oodesign.com/factory-method-pattern.html
http://www.javaworld.com/article/2077386/learn-java/factory-methods.html
I have created a automation suite in java selenium using testng frame work.Basically in my suite the scenarios are placed in between before and after method.
I want to take the screen shot for each failed and passed test scenario.For that i have created a separate class and calling it in each script to capture the screenshot before the after Method.
The issue that i am facing here is if the scenario is getting failed the script stopped executing and it is not moving to the take screenshot line of code and so it is not capturing the screenshot for the failed ones.
So i want the take screenshot program to be only placed in after method so before the driver quit it will take the screenshot inspite of the scenario result of pass/fail.
I have written code for nearly 20 scenario using testng.
Can some one tel me the code in the after method only to take the screenshot without so much effecting the code which i have written.
The screenshot program should only be in the after method so it will capture teh screen before driver quit.
Make sure you catch exceptions so you won't exit the code prematurely.
For example, this is how I take screenshots after every test run (passed or failed). I use the exception value (if any) to dynamically name the screenshot files.
First, an example test method:
[DataSource("System.Data.SqlClient", "Data Source=DEV338\\X2B;Initial Catalog=SeleniumDb;Integrated Security=True",
"dbo.F_single_ErkenningAannemerKlasse1", DataAccessMethod.Sequential), TestMethod]
public void erkenningAannemerKlasse1()
{
try
{
frontUser.erkenningAannemerKlasse1(data);
}
catch (Exception e)
{
exception = e.Message + " " + e.StackTrace;
}
}
Then this method executes after every test. Default behaviour in Microsoft UnitTest framework, in this case.
[TestCleanup()]
public void Cleanup()
{
frontUser.takeScreenshot(data.get("testnaam"), data.get("datarow"), exception);
frontUser.closeBrowser();
}
I am using junit and selenium to test a web application and I have a test suite that I'm running. Sometimes when a web page fails to load properly in the browser, tests will fail through no fault of the actual application. To remedy this I wanted to catch any first time errors and run tests again to ensure that the problem indeed lies with the application.
I've tried the code below.
try{
ts.runTest(ts.testAt(testNum), a);
}
catch (Error er){
ts.runTest(ts.testAt(testNum), a);
}
catch (Exception e){
ts.runTest(ts.testAt(testNum), a);
}
Ive also tried this
ts.runTest(ts.testAt(testNum), a);
if (!a.wasSuccessful()){
ts.runTest(ts.testAt(testNum), a);
if (!a.wasSuccessful()){
fail();
System.out.println("Test "+testNum+" failed");
}
}
But in both tests the program stops testing entirely the first time it encounters an error. I need to be able to run these tests multiple times despite failures.
I beleive the easiest way to handle this issue will be to check if your page has loaded before even start executing tests. I am not sure how your tests navigation works. But for me it's something like this we use
public SomePage ClickUpdate()
{
Driver.FindElement(By.Id("MyId")).Click();
//taking page objects in return
return new SomePage (Driver);
}
And inside the SomePage() object use a unique selector and inside the constructor wait until that to exist and wrap that in try catch
try
{
var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(5));
wait.Until(ExpectedConditions.ElementExists(By.Id("Your Id")));
}
catch (YourException)
{
Driver.Navigate().Refresh();
// Or you can perform another click to allow the page to load
var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(5));
wait.Until(ExpectedConditions.ElementExists(By.Id("Your Id")));
}
Mine is C#. Hope this helps
I need to test a webpage via desktop application, I'm trying to use
the selenium IDE, I had sucess to create the test cases, but I'm not
able to execute them on java.
I've been looking for something helpful, but I can't find any help at all.
Thank you
A framework that has been created for just this cause, (it's in Java) can be downloaded here or you can check the project out from github here.
This project was designed to be very simple, yet very effective. This type of framework is a "free version" of my interpretation of a framework that I use every day in production-type environments.
There is a sample test that is enclosed in the project named SampleFunctionalTest.java. Assuming you follow the ReadMe to the T, you should have no problem getting started.
Here is what a test would look like in this framework.
#Config(url = "http://ddavison.github.io/tests/getting-started-with-selenium.htm", browser = Browser.FIREFOX) // You are able to specify a "base url" for your test, from which you will test. You may leave `browser` blank.
public class SampleFunctionalTest extends AutomationTest {
/**
* You are able to fire this test right up and see it in action. Right click the test() method, and click "Run As... jUnit test".
*
* The purpose of this is to show you how you can continue testing, just by taking the semi colon out, and continuing with your test.
*/
#Test
public void test() {
// click / validateAttribute
click(props.get("click"))
.validateAttribute(props.get("click"), "class", "success") // validate that the class indeed added.
// setText / validateText
.setText(By.id("setTextField"), "woot!")
.validateText(By.id("setTextField"), "woot!") // validates that it indeed set.
// check / uncheck
.check(By.id("checkbox"))
.validateChecked(By.id("checkbox")) // validate that it checked
.check(props.get("radio.2")) // remember that props come from <class name>.properties, and are always CSS selectors. (why use anything else, honestly.)
.validateUnchecked(props.get("radio.1")) // since radio 1 was selected by default, check the second one, then validate that the first radio is no longer checked.
// select from dropdowns.
.selectOptionByText(By.xpath("//select[#id='select']"), "Second") // just as a proof of concept that you can select on anything. But don't use xpath!!
.validateText(By.id("select"), "2") // validateText() will actually return the value="" attr of a dropdown, so that's why 2 works but "Second" will not.
.selectOptionByValue(By.cssSelector("select#select"), "3")
.validateText(props.get("select"), "3")
// frames
.switchToFrame("frame") // the id="frame"
.validatePresent(By.cssSelector("div#frame_content"))
// windows
.switchToWindow("Getting Started with Selenium") // switch back to the test window.
.click(By.linkText("Open a new tab / window"))
.waitForWindow("Google") // waits for the url. Can also be the you are expecting. :) (regex enabled too)
.setText(By.name("q"), "google!")
.closeWindow(); // we've closed google, and back on the getting started with selenium page.
}
}
You should create an instance of a WebDriver and call methods on the instance of that object.
An easy example is shown here: http://www.seleniumhq.org/docs/03_webdriver.jsp#introducing-the-selenium-webdriver-api-by-example
I hope you have created the script in webdriver.
Now in the script recorded by the selenium ide you have three methods called
setup, testSomeName and tearDown.
From the very basic: to run this script all you need to do is create a main method in the same class and in that you need to call these methods in the same order as specified above.
After that you just need to run that program.
Here is an example to make it more clear:
public class p_adjcb {
public void setUp() throws Exception {
}
public void testP_adjcb() throws Exception {
}
public void tearDown() throws Exception {
}
public static void main(String[] args) {
p_adjcb obj = new p_adjcb();
try {
obj.setUp();
obj.testP_adjcb();
obj.tearDown();
} catch (Exception ex) {
}
}
}
If you get any compiler error make sure you have downloaded the selenium-standalone-server.jar file and added it to your class path.
This is a very basic start. Later on you may need to use som framework like junit.
Hope it helps.