This post was updated on .
Hi guys!
Jenkins has problem to take screenshot when a test is failed. This is the my code: package com.ndg.test.selenium; import static com.thoughtworks.selenium.grid.tools.ThreadSafeSeleniumSessionStorage.session; import java.io.File; import java.util.Date; import org.testng.ITestResult; import org.testng.Reporter; import org.testng.TestListenerAdapter; public class Screenshot extends TestListenerAdapter { @Override public void onTestFailure(ITestResult result) { File file = new File("/s:/screenshots"); Reporter.setCurrentTestResult(result); Date t = new Date(result.getStartMillis()); String fileName= Integer.toString(t.getYear()) + Integer.toString(t.getMonth()) + Integer.toString(t.getDate()) + Integer.toString(t.getHours()) + Integer.toString(t.getMinutes()) + Integer.toString(t.getSeconds()) + ".png"; String filePath = file.getAbsolutePath() + "/" + result.getMethod() + "/" + fileName; System.out.println("Writing screen shot to: " + filePath); Reporter.log("screenshot saved at " + filePath); Reporter.log("<a href='/userContent/selenium/screenshots/" + result.getMethod() + "/" + fileName + "' height='100' width='100'/>View Screenshot</a>"); //session().windowMaximize(); session().captureScreenshot(filePath); Reporter.setCurrentTestResult(null); } @Override public void onTestSkipped(ITestResult result) { // will be called after test will be skipped } @Override public void onTestSuccess(ITestResult result) { // will be called after test will pass } } What do I wrong? Thanks GC |
Administrator
|
Not quite sure the problem you face. But let me post how I take screen shot on test failure in tear down of TestNG where I close the browser -
/** * Closes browser * * @throws IOException */ @AfterMethod(alwaysRun = true) public void shutDownDriver(ITestResult result) throws IOException { if (result.getStatus() == 3) { throw new SkipException("!!! Test method was skipped"); } // Capture screen shot on test failure if (!result.isSuccess()) { File imageFile = ((TakesScreenshot) driver) .getScreenshotAs(OutputType.FILE); String failureImageFileName = result.getMethod().getMethodName() + " on: " + new GregorianCalendar().getTime().toString() + ".png"; File failureImageFile = new File(failureImageFileName); FileUtils.moveFile(imageFile, failureImageFile); // Move failure image to corresponding browser folder if (((RemoteWebDriver) driver).getCapabilities() .getBrowserName().equalsIgnoreCase("firefox")) { FileUtils.moveFileToDirectory(failureImageFile, new File( "testfailureimages/firefox"), true); } else if (((RemoteWebDriver) driver).getCapabilities() .getBrowserName().equalsIgnoreCase("chrome")) { FileUtils.moveFileToDirectory(failureImageFile, new File( "testfailureimages/chrome"), true); } else if (((RemoteWebDriver) driver).getCapabilities() .getBrowserName().equalsIgnoreCase("chrome")) { FileUtils.moveFileToDirectory(failureImageFile, new File( "testfailureimages/internet explorer"), true); } } driver.manage().deleteAllCookies(); driver.quit(); } If you notice I also move failure images of a browser to a corresponding folder that is testfailureimages/firefox, testfailureimages/chrome etc. Does this help? n.b. for code formatting while posting the code in this forum, you could use tag . It is available under More menu.
~ seleniumtests.com
|
This is very interesting, I don't use webdriver, but tomorrow I will try ;)
The try-catch could be a problem to take screenshot? GC |
Administrator
|
which "try-catch" are you referring to here?
~ seleniumtests.com
|
In my selenium test there are more try-catch:
public void CreateUser(String name) throws Exception { try{ String lastName = name.trim().toLowerCase(); //session().open("/ni/admin/userList.asp"); session().open("/ui/user/list.php"); session().waitForPageToLoad("30000"); //session().click("//input[@value='new user']"); session().click("//tr[2]/td[6]/span"); //add new //session().waitForPageToLoad("30000"); Thread.sleep(6000); session().select("role_id", "label=" + name); //session().click("id=role_idchzn_o_8"); //Agency if(name=="Admin"){ session().click("id=role_idchzn_o_1"); } else if(name=="Editor"){ session().click("id=role_idchzn_o_2"); .... } session().type("name", "selenium_" + lastName); session() .type("password", "xxxx"); session() .type("password_check", "xxxx"); session().click("active"); session().type("firstname", "Selenium"); session().type("lastname", name); //session().click("//input[@value='Create']"); session().click("updateButton"); //add user //session().waitForPageToLoad("30000"); Thread.sleep(6000); } catch(Throwable createUser){ fail("Test doesn't work with" + name); Thread.sleep(1000); } these try-catch....could be a problem? |
Administrator
|
As far as I see should not be.
On a different note, try to reduce those sleep statements. Do a conditional wait instead of hard coding sleep statements. You may find this post interesting. But to be able to use my previous screen shot example you would have to use WebDriver API.
~ seleniumtests.com
|
Output Jenkins: :(
[java] FAILED: Admin_Users on instance null(com.ndg.test.selenium.adagioui.inizialize_sys) [java] com.thoughtworks.selenium.SeleniumException: ERROR: Problem capturing screenshot: null [java] at com.thoughtworks.selenium.HttpCommandProcessor.throwAssertionFailureExceptionOrError(HttpCommandProcessor.java:112) [java] at com.thoughtworks.selenium.HttpCommandProcessor.doCommand(HttpCommandProcessor.java:106) [java] at com.thoughtworks.selenium.DefaultSelenium.captureScreenshot(DefaultSelenium.java:744) [java] at com.ndg.test.selenium.AdagioUITestcase.Exception_byGiuseppe(AdagioUITestcase.java:332) [java] at com.ndg.test.selenium.adagioui.inizialize_sys.inizializeSystem(inizialize_sys.java:77) [java] at com.ndg.test.selenium.adagioui.inizialize_sys.Admin_Users(inizialize_sys.java:25) [java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [java] at java.lang.reflect.Method.invoke(Method.java:597) [java] at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:76) [java] at org.testng.internal.Invoker.invokeMethod(Invoker.java:673) [java] at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:846) [java] at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1170) [java] at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125) [java] at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109) [java] at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [java] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [java] at java.lang.Thread.run(Thread.java:662) My test: public void inizializeSystem(int systemId) throws Exception { try{ //new base type creative_base_type creativeBaseType = new creative_base_type(); creativeBaseType.CreativeBaseType(systemId, 0); //value_context is 0 for doesn't delete creative base type //new template type creative_template_type creativeTemplateType = new creative_template_type(); creativeTemplateType.CreativeTemplateType(systemId, 0); //value_context is 0 for doesn't delete template base type //new advertiser test advertiser_edit CreateAdv = new advertiser_edit(); CreateAdv.CreateAdv(systemId, 0); //new creative creative_edit creativeEdit = new creative_edit(); creativeEdit.add_creative_to(systemId, 0); /* //new location tree session().click("itemMenu_admin_3"); session().waitForPageToLoad("150000"); Thread.sleep(1000); if(session().isElementPresent("//html/body/div[4]/form/table/tbody/tr[4]/td[2]/table/tbody/tr/td[3]/div[1]/h4[1]/b")){ assertNotNull("There isn't tree!!, system: "+systemId); Thread.sleep(1000); } else { session().type("id=tree", "@Publisher\nEN=Demo EN\n#\n@Website\nW1=Website 1\n#\n@Section\nHP=Home Page\n#\n@Section\nROS=Rest of site\n#\n@Page\nPG=Special Page\n#\n@Website\nW2=Website 2\n#\n@Section\nHP=Home Page\n#\n@Section\nROS=Rest of site"); session().click("name=updateButton"); session().waitForPageToLoad("300000"); Thread.sleep(2000); } //new location location_add addLocation = new location_add(); addLocation.addLocation(systemId, 0); */ //new campaign campaign_edit CreateCampaign = new campaign_edit(); CreateCampaign.CreateCampaign(systemId); } catch(Throwable inizializeSystem){ Exception_byGiuseppe(inizializeSystem, systemId); Thread.sleep(1000); } } } Why?? So, to first error Jenkins stop run immediatly. If I delete in try-catch this Exception_byGiuseppe then works, but don't takes screenshot. |
In you previous code, where do you take the screen shot?
|
So:
/** Exception Class takes the operative system, ** ** object with error, and capture the screenshot **/ public void Exception_byGiuseppe(Throwable page_with_problems, int systemId){ String SO = session().getEval("navigator.platform"); //takes operative system String objectWithError = page_with_problems.getLocalizedMessage(); //takes object with error if (SO.equals("Linux i686")){ //Linux File file = new File("/home/giuseppe/Scrivania/selenium_errors_screenshot"); String fileName = objectWithError+" ["+getClass().getName()+"] [system:"+systemId+"] ["+date_hour+".png"; fileName = fileName.replace('/', '-'); String filePath = file.getAbsolutePath() + "/" + fileName; session().captureScreenshot(filePath); } else { //Windows File file = new File("C:\\selenium_errors_screenshot"); //String fileName = objectWithError+" ["+getClass().getName()+"] [system:"+systemId+"] ["+date_hour+".png"; String fileName = objectWithError + " on: " + new GregorianCalendar().getTime().toString() + ".png"; fileName = fileName.replace('\\', '-'); String filePath = file.getAbsolutePath() + "\\" + fileName; session().captureScreenshot(filePath); } } |
Administrator
|
Looks like by the time control comes to -
session().captureScreenshot(filePath); your session is null. Can you keep a break point and check?
~ seleniumtests.com
|
On my machine works very good if I launch test with normal step-testNG, with Jenkins no.
If I comment this code, then works in Jenkins....but at the end of run of Jenkins, I have a error messagge: [java] FAILED: Admin_Users on instance null(com.ndg.test.selenium.adagioui.inizialize_sys) [java] com.thoughtworks.selenium.SeleniumException: ERROR: Problem capturing screenshot: null [java] at com.thoughtworks.selenium.HttpCommandProcessor.throwAssertionFailureExceptionOrError(HttpCommandProcessor.java:112) [java] at com.thoughtworks.selenium.HttpCommandProcessor.doCommand(HttpCommandProcessor.java:106) [java] at com.thoughtworks.selenium.DefaultSelenium.captureScreenshot(DefaultSelenium.java:744) [java] at com.ndg.test.selenium.AdagioUITestcase.Exception_byGiuseppe(AdagioUITestcase.java:332) [java] at com.ndg.test.selenium.adagioui.inizialize_sys.inizializeSystem(inizialize_sys.java:77) [java] at com.ndg.test.selenium.adagioui.inizialize_sys.Admin_Users(inizialize_sys.java:25) [java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [java] at java.lang.reflect.Method.invoke(Method.java:597) [java] at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:76) [java] at org.testng.internal.Invoker.invokeMethod(Invoker.java:673) [java] at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:846) [java] at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1170) [java] at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125) [java] at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109) [java] at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [java] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [java] at java.lang.Thread.run(Thread.java:662) |
Administrator
|
This is little confusing. If you comment the screen shot part of code then you should not see error message about screen shot it self, that is -
[java] com.thoughtworks.selenium.SeleniumException: ERROR: Problem capturing screenshot: null Either I missed some thing or you did not post entire code. To simplify it, can you write a small test and check if it succeeds in taking screen shot on Jenkins?
~ seleniumtests.com
|
Sure, after lunch I will create a small test..thanks Tarun;)
|
I'm working on it, but think the problem is on name screenshot.
I will update you!:) |
Dear Tarun, I'm sorry if I've got a bit of time to respond, but I want to do it well.
My test environment is so formed: - 3 computers windows where open web pages to control; - 1 ubuntu computer with the database where the web interface takes the values; - Ubuntu on my computer where I prepare the tests and try to configure it with your help. :) Did I mention that I work with Selenium RC for now. Using Jenkins to run my tests and view reports. The three machines are .31, .30 and .32. In the .31 launch hudson, the hub and 3 browsers, in .30 launch others 3 browsers and in .32 launch others 3 browsers. Now I show you the most important files and a very simple example of one of my tests: -testng.xml <suite name="X UI Selenium Test Suite" parallel="methods" thread-count="10" verbose="3" configfailurepolicy="continue"> <listeners> <listener class-name="com.ndg.test.selenium.Screenshot" /> </listeners> <test name="X UI Selenium Tests"> <packages> <package name="com.ndg.test.selenium.x.*" /> </packages> <groups> <run> <define name="all"> <include name="seltest"/> <include name="test"/> </define> <include name="stupidtest"/> </run> </groups> </test> </suite> -build.xml <project name="Selenium Tests" default="run" basedir="."> <description>Selenium Tests Description</description> <property name="rootdir" value="${basedir}"/> <property file="${rootdir}/project.properties"/> <property name="name" value="Selenium Grid Test"/> <property name="artifact" value="selenium-grid-demo"/> <property name="version" value="SNAPSHOT"/> <property name="selenium.version" value="SET ME"/> <property name="build.src" location="src"/> <import file="${rootdir}/common-build.xml" /> <property name="webSite" value="http://xxxx.it" /> <property name="seleniumHost" value="zzzz.31" /> <property name="seleniumPort" value="yyyy" /> <property name="browser" value="win_firefox" /> <path id="compile.classpath"> <fileset dir="${rootdir}/lib" includes="*.jar"/> <pathelement location="${rootdir}/tools/target/classes"/> <pathelement location="${rootdir}/lib/selenium-grid-tools-1.0.8.jar"/> <pathelement path="${java.class.path}/"/> </path> <path id="runtime.classpath"> <path refid="compile.classpath"/> <pathelement path="${build.output}/"/> </path> <target name="runtests" depends="compile" description="Run Selenium tests in parallel (7 threads)"> <echo>Running Tests on ${seleniumHost}</echo> <property name="javatestresult" value="-1"/> <java classpathref="runtime.classpath" classname="org.testng.TestNG" resultproperty="javatestresult"> <sysproperty key="java.security.policy" file="testng.policy"/> <sysproperty key="webSite" value="${webSite}" /> <sysproperty key="seleniumHost" value="${seleniumHost}" /> <sysproperty key="seleniumPort" value="${seleniumPort}" /> <sysproperty key="browser" value="${browser}" /> <sysproperty key="org.uncommons.reportng.escape-output" value="false"/> <arg value="-d" /> <arg value="${basedir}/target/reports" /> <arg value="-suitename" /> <arg value="Selenium Grid Java Sample Test Suite" /> <arg value="-parallel"/> <arg value="methods"/> <arg value="-threadcount"/> <arg value="15"/> <arg value="-listener"/> <arg value="com.ndg.test.selenium.Screenshot"/> <arg value="-groups" /> <arg value="${groups}" /> <arg value="testng.xml"/> </java> <mkdir dir="${basedir}/target/reports/fancy"/> <xslt in="${basedir}/target/reports/testng-results.xml" style="${basedir}/report/testng-results.xsl" out="${basedir}/target/reports/fancy/index.html" classpathref="runtime.classpath" processor="SaxonLiaison"> <param name="testNgXslt.outputDir" expression="${basedir}/target/reports/fancy/"/> <param name="testNgXslt.sortTestCaseLinks" expression="true"/> <param name="testNgXslt.testDetailsFilter" expression="FAIL,SKIP,PASS"/> </xslt> <condition property="allok"> <equals arg1="${javatestresult}" arg2="0"/> </condition> </target> <target name="fail" depends="runtests" unless="allok"> <fail>"Some Tests Failed!"</fail> </target> <target name="run" depends="runtests, fail" if="allok"> <echo>Tests ran ok</echo> </target> <target name="build" depends="compile"/> <target name="dist" depends="build"/> <target name="coverage-analysis" /> </project> -Screenshot.java package com.ndg.test.selenium; import static com.thoughtworks.selenium.grid.tools.ThreadSafeSeleniumSessionStorage.session; import java.io.File; import java.util.Date; import org.openqa.selenium.Dimension; import org.openqa.selenium.internal.seleniumemulation.Windows; import org.testng.ITestResult; import org.testng.Reporter; import org.testng.TestListenerAdapter; public class Screenshot extends TestListenerAdapter{ @Override public void onTestFailure(ITestResult result){ try { Screenshot.captureScreenshot(result); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void onTestSkipped(ITestResult result){ //will be called after test will be skipped } @Override public void onTestSuccess(ITestResult result){ //will be called after test will pass } /** * Synchronised code to capture the screenshot only one thread at a time so we can run in parallel * @param result * @throws InterruptedException */ private static synchronized void captureScreenshot(ITestResult result) throws InterruptedException { File file = new File("s:/screenshots"); if (!file.exists()) { file = new File("/home/xxxx/Scrivania/selenium_errors_screenshot/"); } Reporter.setCurrentTestResult(result); Date t = new Date(result.getStartMillis()); String fileName = Integer.toString(t.getYear()) + Integer.toString(t.getMonth()) + Integer.toString(t.getDate()) + Integer.toString(t.getHours()) + Integer.toString(t.getMinutes()) + Integer.toString(t.getSeconds()) + ".png"; //String fileName = result.getMethod().getMethodName() + " on: " //+ new GregorianCalendar().getTime().toString() + ".png"; String filePath = file.getAbsolutePath() + "\\" + result.getMethod() + "\\" + fileName; // Create unique file name File ScreenshotFile = new File(filePath); int counter = 2; while (ScreenshotFile.exists()) { ScreenshotFile = new File(filePath + counter); ++counter; } System.out.println("Writing screen shot to: " + filePath); Reporter.log("screenshot saved at " + filePath); Reporter.log("<a href='/userContent/selenium/screenshots/" + result.getMethod() + "/" + fileName + "' height='100' width='100'/>View Screenshot</a>"); //session().getEval("window.resizeTo(1600, 900); window.moveTo(0,0);"); String screenshot_title = "ScreenshotThis"; String orig_title_window = session().getTitle(); session().runScript("document.title='"+screenshot_title+"'"); //session().selectWindow(screenshot_title); session().windowFocus(); session().windowMaximize(); session().captureScreenshot(filePath); session().runScript("document.title='"+orig_title_window+"'"); Reporter.setCurrentTestResult(null); } } -stupid_test.java package com.ndg.test.selenium.xxxx; import static com.thoughtworks.selenium.grid.tools.ThreadSafeSeleniumSessionStorage.session; import java.lang.reflect.Method; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.ndg.test.selenium.yyyy; public class stupid_test extends yyyy{ @DataProvider(name="dp", parallel=true) public Object[][] createData(Method m) { System.out.println(m.getName()); //print test method name return new Object[][] { new Object[] { 1, "Admin" }, new Object[] { 2, "Admin" }, new Object[] { 3, "Admin" }, new Object[] { 4, "Admin" }, new Object[] { 5, "Admin" }, new Object[] { 6, "Admin" }, new Object[] { 7, "Admin" }, new Object[] { 8, "Admin" }, new Object[] { 9, "Admin" }, new Object[] { 10, "Admin" } }; } @Test(dataProvider = "dp", groups={"stupidtest"}) public void Admin_Users(int systemId, String role) throws Exception { String loginName = role.trim().toLowerCase(); this.login(systemId, loginName); this.test(systemId); } public void test(int systemId) throws Exception { session().click("itemMenu_adv_1"); session().waitForPageToLoad("90000"); wait_load_grid_list(); //This error isn't casual!! consume_Confirmation_Alert(); deselect_filters_advertiser(systemId); } } Now I'll explain what I would do: I run tests in parallel, so I have 10 windows remote control open on the machine .31, and when an error occurs on the x window(system y), I would like to focus on this, take a screenshot and close, while the others work, but synchronized....and so on until the close of all the tests on the 10 browser. The architecture works well, but I can not finalize the final step when the error occurs, focus doesn't work and then the screenshots take are wrong! Thanks in advance Tarun. I hope this will serve as a help to someone. :) |
My post is very large!:)
can you help or advise me? |
Administrator
|
Sorry, but I am not able to figure out what goes wring here.
~ seleniumtests.com
|
Free forum by Nabble | Edit this page |