├── test-output ├── old │ ├── TestNGSuite │ │ ├── Test.properties │ │ ├── Test1.properties │ │ ├── groups.html │ │ ├── methods-not-run.html │ │ ├── main.html │ │ ├── index.html │ │ ├── classes.html │ │ ├── reporter-output.html │ │ ├── testng.xml.html │ │ ├── toc.html │ │ ├── methods.html │ │ └── methods-alphabetical.html │ ├── Default suite │ │ ├── groups.html │ │ ├── Default test.properties │ │ ├── reporter-output.html │ │ ├── methods-not-run.html │ │ ├── main.html │ │ ├── index.html │ │ ├── classes.html │ │ ├── testng.xml.html │ │ ├── methods.html │ │ ├── methods-alphabetical.html │ │ └── toc.html │ └── index.html ├── failed.png ├── passed.png ├── skipped.png ├── collapseall.gif ├── bullet_point.png ├── navigator-bullet.png ├── testng.css ├── Default suite │ ├── Default test.xml │ └── Default test.html ├── junitreports │ ├── TEST-testScripts.Test1.xml │ ├── TEST-testScripts.TestNG.xml │ ├── TEST-testScripts.TestMedia.xml │ ├── TEST-testScripts.TestExcel.xml │ └── TEST-testScripts.TestScreenshot.xml ├── TestNGSuite │ ├── Test1.xml │ ├── Test.xml │ ├── testng-failed.xml │ ├── Test1.html │ └── Test.html ├── testng-failed.xml ├── emailable-report.html ├── testng-reports.js ├── testng-reports.css ├── testng-results.xml └── index.html ├── Excel ├── TestXLS.xls ├── TestXLSX.xlsx └── TestAnyOther.xlsm ├── target └── classes │ ├── utility │ ├── Platform.class │ ├── Screenshot.class │ ├── MediaLibrary.class │ ├── TestListener.class │ └── ExcelExportAndFileIO.class │ ├── testScripts │ ├── BaseClass.class │ ├── TestExcel.class │ ├── TestMedia.class │ └── TestScreenshot.class │ ├── gestures │ └── AndroidGesture.class │ └── resources │ ├── testExcel.xml │ ├── testMedia.xml │ └── testScreenshot.xml ├── Screenshots ├── testSkip_SKIP_20190303_232918.png ├── testFail_START_20190303_232917.png ├── testPass_START_20190303_232915.png ├── testFail_FAILURE_20190303_232918.png ├── testPass_SUCCESS_20190303_232917.png ├── Search_Text_Box_After_20190303_232916.png └── Search_Text_Box_Before_20190303_232916.png ├── src ├── resources │ ├── testExcel.xml │ ├── testMedia.xml │ └── testScreenshot.xml ├── testScripts │ ├── TestMedia.java │ ├── BaseClass.java │ ├── TestExcel.java │ └── TestScreenshot.java ├── utility │ ├── Platform.java │ ├── TestListener.java │ ├── ExcelExportAndFileIO.java │ ├── MediaLibrary.java │ └── Screenshot.java └── gestures │ └── AndroidGesture.java ├── .gitignore ├── README.md └── pom.xml /test-output/old/TestNGSuite/Test.properties: -------------------------------------------------------------------------------- 1 | [SuiteResult context=Test] -------------------------------------------------------------------------------- /test-output/old/TestNGSuite/Test1.properties: -------------------------------------------------------------------------------- 1 | [SuiteResult context=Test1] -------------------------------------------------------------------------------- /test-output/old/TestNGSuite/groups.html: -------------------------------------------------------------------------------- 1 |

Groups used for this test run

-------------------------------------------------------------------------------- /test-output/old/Default suite/groups.html: -------------------------------------------------------------------------------- 1 |

Groups used for this test run

-------------------------------------------------------------------------------- /test-output/old/Default suite/Default test.properties: -------------------------------------------------------------------------------- 1 | [SuiteResult context=Default test] -------------------------------------------------------------------------------- /test-output/old/Default suite/reporter-output.html: -------------------------------------------------------------------------------- 1 |

Reporter output

-------------------------------------------------------------------------------- /Excel/TestXLS.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/Excel/TestXLS.xls -------------------------------------------------------------------------------- /test-output/old/TestNGSuite/methods-not-run.html: -------------------------------------------------------------------------------- 1 |

Methods that were not run

2 |
-------------------------------------------------------------------------------- /Excel/TestXLSX.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/Excel/TestXLSX.xlsx -------------------------------------------------------------------------------- /test-output/old/Default suite/methods-not-run.html: -------------------------------------------------------------------------------- 1 |

Methods that were not run

2 |
-------------------------------------------------------------------------------- /test-output/failed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/test-output/failed.png -------------------------------------------------------------------------------- /test-output/passed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/test-output/passed.png -------------------------------------------------------------------------------- /Excel/TestAnyOther.xlsm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/Excel/TestAnyOther.xlsm -------------------------------------------------------------------------------- /test-output/skipped.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/test-output/skipped.png -------------------------------------------------------------------------------- /test-output/collapseall.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/test-output/collapseall.gif -------------------------------------------------------------------------------- /test-output/bullet_point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/test-output/bullet_point.png -------------------------------------------------------------------------------- /test-output/navigator-bullet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/test-output/navigator-bullet.png -------------------------------------------------------------------------------- /target/classes/utility/Platform.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/target/classes/utility/Platform.class -------------------------------------------------------------------------------- /target/classes/utility/Screenshot.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/target/classes/utility/Screenshot.class -------------------------------------------------------------------------------- /target/classes/testScripts/BaseClass.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/target/classes/testScripts/BaseClass.class -------------------------------------------------------------------------------- /target/classes/testScripts/TestExcel.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/target/classes/testScripts/TestExcel.class -------------------------------------------------------------------------------- /target/classes/testScripts/TestMedia.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/target/classes/testScripts/TestMedia.class -------------------------------------------------------------------------------- /target/classes/utility/MediaLibrary.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/target/classes/utility/MediaLibrary.class -------------------------------------------------------------------------------- /target/classes/utility/TestListener.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/target/classes/utility/TestListener.class -------------------------------------------------------------------------------- /Screenshots/testSkip_SKIP_20190303_232918.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/Screenshots/testSkip_SKIP_20190303_232918.png -------------------------------------------------------------------------------- /target/classes/gestures/AndroidGesture.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/target/classes/gestures/AndroidGesture.class -------------------------------------------------------------------------------- /Screenshots/testFail_START_20190303_232917.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/Screenshots/testFail_START_20190303_232917.png -------------------------------------------------------------------------------- /Screenshots/testPass_START_20190303_232915.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/Screenshots/testPass_START_20190303_232915.png -------------------------------------------------------------------------------- /target/classes/testScripts/TestScreenshot.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/target/classes/testScripts/TestScreenshot.class -------------------------------------------------------------------------------- /test-output/old/TestNGSuite/main.html: -------------------------------------------------------------------------------- 1 | Results for TestNGSuite 2 | Select a result on the left-hand pane. 3 | -------------------------------------------------------------------------------- /Screenshots/testFail_FAILURE_20190303_232918.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/Screenshots/testFail_FAILURE_20190303_232918.png -------------------------------------------------------------------------------- /Screenshots/testPass_SUCCESS_20190303_232917.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/Screenshots/testPass_SUCCESS_20190303_232917.png -------------------------------------------------------------------------------- /target/classes/utility/ExcelExportAndFileIO.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/target/classes/utility/ExcelExportAndFileIO.class -------------------------------------------------------------------------------- /test-output/old/Default suite/main.html: -------------------------------------------------------------------------------- 1 | Results for Default suite 2 | Select a result on the left-hand pane. 3 | -------------------------------------------------------------------------------- /Screenshots/Search_Text_Box_After_20190303_232916.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/Screenshots/Search_Text_Box_After_20190303_232916.png -------------------------------------------------------------------------------- /Screenshots/Search_Text_Box_Before_20190303_232916.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sameeksha-sahib/selenium-utility/HEAD/Screenshots/Search_Text_Box_Before_20190303_232916.png -------------------------------------------------------------------------------- /test-output/old/TestNGSuite/index.html: -------------------------------------------------------------------------------- 1 | Results for TestNGSuite 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /test-output/old/Default suite/index.html: -------------------------------------------------------------------------------- 1 | Results for Default suite 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/resources/testExcel.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /target/classes/resources/testExcel.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /test-output/testng.css: -------------------------------------------------------------------------------- 1 | .invocation-failed, .test-failed { background-color: #DD0000; } 2 | .invocation-percent, .test-percent { background-color: #006600; } 3 | .invocation-passed, .test-passed { background-color: #00AA00; } 4 | .invocation-skipped, .test-skipped { background-color: #CCCC00; } 5 | 6 | .main-page { 7 | font-size: x-large; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /test-output/Default suite/Default test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /test-output/junitreports/TEST-testScripts.Test1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/resources/testMedia.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /target/classes/resources/testMedia.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/resources/testScreenshot.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /target/classes/resources/testScreenshot.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /test-output/old/Default suite/classes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
Class nameMethod nameGroups
testScripts.Test1  
@Test
 test 
@BeforeClass
@BeforeMethod
@AfterMethod
@AfterClass
29 | -------------------------------------------------------------------------------- /src/testScripts/TestMedia.java: -------------------------------------------------------------------------------- 1 | package testScripts; 2 | 3 | import org.testng.annotations.Test; 4 | 5 | import utility.MediaLibrary; 6 | 7 | public class TestMedia extends BaseClass{ 8 | 9 | @Test (priority = 0) 10 | public void testVideo() throws Exception { 11 | MediaLibrary.playMedia(driver, "video", 0); 12 | 13 | Thread.sleep(500); 14 | 15 | MediaLibrary.pauseMedia(driver, "video", 0); 16 | } 17 | 18 | @Test (priority = 1) 19 | public void testAudio() throws Exception { 20 | 21 | driver.get("http://www.russianlessons.net/audio/audio-test.php"); 22 | 23 | MediaLibrary.playMedia(driver, "audio", 1); 24 | 25 | Thread.sleep(500); 26 | 27 | MediaLibrary.pauseMedia(driver, "audio", 1); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test-output/old/Default suite/testng.xml.html: -------------------------------------------------------------------------------- 1 | testng.xml for Default suite<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite guice-stage="DEVELOPMENT" name="Default suite">
  <test thread-count="5" verbose="2" name="Default test">
    <classes>
      <class name="testScripts.Test1"/>
    </classes>
  </test> <!-- Default test -->
</suite> <!-- Default suite -->
-------------------------------------------------------------------------------- /test-output/old/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

Test results

6 | 7 | 8 | 9 |
SuitePassedFailedSkippedtestng.xml
Total111 
TestNGSuite111Link
10 | -------------------------------------------------------------------------------- /test-output/old/Default suite/methods.html: -------------------------------------------------------------------------------- 1 |

Methods run, sorted chronologically

>> means before, << means after


Default suite

(Hover the method name to see the test class name)

2 | 3 | 4 | 5 | 6 |
TimeDelta (ms)Suite
configuration
Test
configuration
Class
configuration
Groups
configuration
Method
configuration
Test
method
ThreadInstances
19/01/07 12:32:04 0      testmain@1698097425
7 | -------------------------------------------------------------------------------- /test-output/old/Default suite/methods-alphabetical.html: -------------------------------------------------------------------------------- 1 |

Methods run, sorted chronologically

>> means before, << means after


Default suite

(Hover the method name to see the test class name)

2 | 3 | 4 | 5 | 6 |
TimeDelta (ms)Suite
configuration
Test
configuration
Class
configuration
Groups
configuration
Method
configuration
Test
method
ThreadInstances
19/01/07 12:32:04 0      testmain@1698097425
7 | -------------------------------------------------------------------------------- /test-output/old/TestNGSuite/classes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
Class nameMethod nameGroups
testScripts.TestScreenshot  
@Test
 testPass 
 testSkip 
 testFail 
@BeforeClass
@BeforeMethod
@AfterMethod
@AfterClass
37 | -------------------------------------------------------------------------------- /test-output/TestNGSuite/Test1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /test-output/TestNGSuite/Test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /test-output/testng-failed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /test-output/TestNGSuite/testng-failed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /test-output/old/TestNGSuite/reporter-output.html: -------------------------------------------------------------------------------- 1 |

Reporter output

2 | 3 | 4 | 5 | 6 | 7 |
Result status: 1
Result status: 2
Result status: 3
-------------------------------------------------------------------------------- /test-output/old/TestNGSuite/testng.xml.html: -------------------------------------------------------------------------------- 1 | testng.xml for TestNGSuite<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="TestNGSuite" guice-stage="DEVELOPMENT">
  <parameter name="webURL" value="https://www.google.com/"/>
  <parameter name="webBrowser" value="chrome"/>
  <listeners>
    <listener class-name="utility.TestListener"/>
  </listeners>
  <test thread-count="5" name="Test">
    <classes>
      <class name="testScripts.TestScreenshot"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- TestNGSuite -->
-------------------------------------------------------------------------------- /src/testScripts/BaseClass.java: -------------------------------------------------------------------------------- 1 | package testScripts; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.support.ui.WebDriverWait; 7 | import org.testng.annotations.AfterSuite; 8 | import org.testng.annotations.BeforeSuite; 9 | import org.testng.annotations.Parameters; 10 | 11 | import utility.Platform; 12 | 13 | public class BaseClass { 14 | 15 | public WebDriver driver; 16 | public WebDriverWait wait; 17 | 18 | 19 | @BeforeSuite 20 | @Parameters(value = {"webBrowser", "webURL"}) 21 | public void setUp(String webBrowser, String webURL) throws Exception { 22 | 23 | // initialize driver 24 | Platform.initializeDriver(webBrowser); 25 | driver = Platform.getDriver(); 26 | 27 | driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); 28 | wait = new WebDriverWait(driver, 10); 29 | 30 | 31 | // Maximize browser and go to required URL 32 | driver.manage().window().maximize(); 33 | driver.get(webURL); 34 | 35 | } 36 | 37 | @AfterSuite 38 | public void tearDown() throws Exception { 39 | driver.quit(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test-output/old/TestNGSuite/toc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Results for TestNGSuite 4 | 5 | 6 | 7 | 8 |

Results for
TestNGSuite

9 | 10 | 11 | 12 | 13 | 17 | 18 | 19 | 20 | 21 | 22 |
1 test1 class3 methods:
14 |   chronological
15 |   alphabetical
16 |   not run (0)
0 groupreporter outputtestng.xml
23 | 24 |

29 |

25 |
Test (1/1/1) 26 | Results 27 |
28 |
30 | -------------------------------------------------------------------------------- /test-output/old/Default suite/toc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Results for Default suite 4 | 5 | 6 | 7 | 8 |

Results for
Default suite

9 | 10 | 11 | 12 | 13 | 17 | 18 | 19 | 20 | 21 | 22 |
1 test1 class1 method:
14 |   chronological
15 |   alphabetical
16 |   not run (0)
0 groupreporter outputtestng.xml
23 | 24 |

29 |

25 |
Default test (1/0/0) 26 | Results 27 |
28 |
30 | -------------------------------------------------------------------------------- /src/testScripts/TestExcel.java: -------------------------------------------------------------------------------- 1 | package testScripts; 2 | 3 | import org.testng.annotations.Test; 4 | 5 | import utility.ExcelExportAndFileIO; 6 | 7 | public class TestExcel { 8 | 9 | @Test 10 | public void testXLSX() throws Exception { 11 | 12 | String sheetName = "Sheet1"; 13 | String[] dataToWriteXLSX = {"XLSX new1", "XLSX new2"}; 14 | String fileNameXLSX = "TestXLSX.xlsx"; 15 | 16 | ExcelExportAndFileIO.writeExcel( fileNameXLSX, sheetName, dataToWriteXLSX); 17 | ExcelExportAndFileIO.readExcel( fileNameXLSX, sheetName); 18 | 19 | } 20 | 21 | @Test 22 | public void testXLS() throws Exception { 23 | 24 | String sheetName = "Sheet1"; 25 | String[] dataToWriteXLS = {"XLS new1", "XLS new2"}; 26 | String fileNameXLS = "TestXLS.xls"; 27 | 28 | ExcelExportAndFileIO.writeExcel( fileNameXLS, sheetName, dataToWriteXLS); 29 | ExcelExportAndFileIO.readExcel( fileNameXLS, sheetName); 30 | 31 | } 32 | 33 | @Test // this should fail 34 | public void testAnyOher() throws Exception { 35 | 36 | String sheetName = "Sheet1"; 37 | String[] dataToWrite = {"fail", "fail"}; 38 | String fileNameXLSM = "TestAnyOther.xlsm"; 39 | 40 | ExcelExportAndFileIO.writeExcel( fileNameXLSM, sheetName, dataToWrite); 41 | ExcelExportAndFileIO.readExcel( fileNameXLSM, sheetName); 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/testScripts/TestScreenshot.java: -------------------------------------------------------------------------------- 1 | package testScripts; 2 | 3 | import java.io.File; 4 | 5 | import org.openqa.selenium.By; 6 | import org.openqa.selenium.WebElement; 7 | import org.testng.Assert; 8 | import org.testng.annotations.Test; 9 | 10 | import utility.Screenshot; 11 | 12 | public class TestScreenshot extends BaseClass { 13 | 14 | @Test(priority = 0) 15 | public void testPass() throws Exception { 16 | System.out.println("In testPass"); 17 | 18 | WebElement searchTextBox = driver.findElement(By.cssSelector(".gLFyf.gsfi")); 19 | 20 | File before = Screenshot.getScreenshotOfElement(driver, searchTextBox, "Search_Text_Box_Before"); 21 | 22 | searchTextBox.sendKeys("Passed Test"); 23 | 24 | File after = Screenshot.getScreenshotOfElement(driver, searchTextBox, "Search_Text_Box_After"); 25 | 26 | Assert.assertFalse(Screenshot.isImageSame(before, after), "Send Key failed"); 27 | } 28 | 29 | @Test (priority = 2) 30 | public void testFail() { 31 | System.out.println("In testFail"); 32 | 33 | WebElement searchTextBox = driver.findElement(By.cssSelector(".gLFyf.gsfi")); 34 | searchTextBox.clear(); 35 | searchTextBox.sendKeys("Failed Test"); 36 | 37 | Assert.fail(); 38 | } 39 | 40 | @Test(dependsOnMethods = { "testFail" }) 41 | public void testSkip() { 42 | System.out.println("In testSkip"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sample selenium-utility project: 2 | 3 | This is a java based sample project with examples to show how to integrate Screenshot with TestNG report, Excel IO, Media library, Android Gesture and coordinate mapper to map CSS coordinates to physical coordinates of android device. 4 | 5 | Setup: 6 | 1. Do initial setup for selenium: https://www.guru99.com/installing-selenium-webdriver.html 7 | 2. Download source zip, extract it and open in eclipse. 8 | 3. Update the project through Maven update (Right click on project in eclipse --> Maven --> Update project) 9 | 4. If error of java binding occurs, right click project in eclipse --> properties --> Java compiler --> Check 'Use compliance from execution environment' option 10 | 5. Download chrome driver: http://chromedriver.chromium.org/downloads and keep the .exe in the project folder. 11 | 6. Download Gecko driver: https://github.com/mozilla/geckodriver/releases and keep the .exe in the project folder. 12 | 7. Download Opera driver: https://github.com/operasoftware/operachromiumdriver/releases and keep the opera driver folder in the project folder 13 | 14 | Note: On windows folder path contains "\\" and on Mac folder path contains "/". 15 | Therefore, change slashes according to your machine in files in folder utility: ExcelExportAndFileIO.java, Screenshot.java 16 | Platform.java 17 | 18 | 8. Run .xml files as TestNG and see test output. 19 | 20 | Happy testing :) 21 | 22 | Some helpful links: 23 | Safari Bug: https://github.com/SeleniumHQ/selenium/issues/6637 Safari issue for getLocation() 24 | Property readyState for media elements: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/readyState 25 | -------------------------------------------------------------------------------- /test-output/old/TestNGSuite/methods.html: -------------------------------------------------------------------------------- 1 |

Methods run, sorted chronologically

>> means before, << means after


TestNGSuite

(Hover the method name to see the test class name)

2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
TimeDelta (ms)Suite
configuration
Test
configuration
Class
configuration
Groups
configuration
Method
configuration
Test
method
ThreadInstances
19/03/03 23:29:04 0 >>setUp      main@1309238149
19/03/03 23:29:14 10012      testPassmain@1309238149
19/03/03 23:29:17 12498      testFailmain@1309238149
19/03/03 23:29:18 14118 <<tearDown      main@1309238149
13 | -------------------------------------------------------------------------------- /test-output/old/TestNGSuite/methods-alphabetical.html: -------------------------------------------------------------------------------- 1 |

Methods run, sorted chronologically

>> means before, << means after


TestNGSuite

(Hover the method name to see the test class name)

2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
TimeDelta (ms)Suite
configuration
Test
configuration
Class
configuration
Groups
configuration
Method
configuration
Test
method
ThreadInstances
19/03/03 23:29:04 0 >>setUp      main@1309238149
19/03/03 23:29:18 14118 <<tearDown      main@1309238149
19/03/03 23:29:17 12498      testFailmain@1309238149
19/03/03 23:29:14 10012      testPassmain@1309238149
13 | -------------------------------------------------------------------------------- /src/utility/Platform.java: -------------------------------------------------------------------------------- 1 | package utility; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | import org.openqa.selenium.chrome.ChromeDriver; 5 | import org.openqa.selenium.chrome.ChromeOptions; 6 | import org.openqa.selenium.firefox.FirefoxDriver; 7 | import org.openqa.selenium.firefox.FirefoxOptions; 8 | import org.openqa.selenium.opera.OperaDriver; 9 | import org.openqa.selenium.safari.SafariDriver; 10 | import org.testng.Assert; 11 | import org.testng.Reporter; 12 | 13 | public class Platform { 14 | 15 | public static WebDriver driver; 16 | private static String USER_DIRECTORY = System.getProperty("user.dir"); 17 | 18 | public static void initializeDriver(String webBrowser) { 19 | 20 | switch (webBrowser) { 21 | case "chrome": 22 | // Set path of chromedriver 23 | System.setProperty("webdriver.chrome.driver", USER_DIRECTORY + "/chromedriver"); 24 | 25 | ChromeOptions cOptions = new ChromeOptions(); // options to disable chrome info-bars 26 | cOptions.addArguments("disable-infobars"); 27 | 28 | driver = new ChromeDriver(cOptions); // initialize driver 29 | break; 30 | case "firefox": 31 | // Set path of geckodriver 32 | System.setProperty("webdriver.gecko.driver", USER_DIRECTORY + "/geckodriver"); 33 | 34 | FirefoxOptions fOptions = new FirefoxOptions(); // initialize FirefoxOptions 35 | fOptions.addArguments("marionette"); 36 | 37 | driver = new FirefoxDriver(); // initialize driver 38 | break; 39 | case "opera": 40 | // Set path of operadriver 41 | System.setProperty("webdriver.opera.driver", USER_DIRECTORY + "/operadriver/operadriver"); 42 | driver = new OperaDriver(); // initialize driver 43 | break; 44 | case "safari": 45 | driver = new SafariDriver(); // initialize driver 46 | break; 47 | default: 48 | Assert.fail( 49 | "Driver Initializing fail: Please enter one of the webBrowser value: safari, chrome, opera, firefox, edge"); 50 | } 51 | } 52 | 53 | public static WebDriver getDriver() { 54 | if (driver != null) { 55 | return driver; 56 | } else { 57 | System.out.println("Driver not initialised"); 58 | Reporter.log("Driver not initialised"); 59 | return driver; 60 | } 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /test-output/Default suite/Default test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | TestNG: Default test 4 | 5 | 6 | 7 | 11 | 53 | 54 | 55 | 56 |

Default test

57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
Tests passed/Failed/Skipped:1/0/0
Started on:Mon Jan 07 12:32:04 IST 2019
Total time:0 seconds (36 ms)
Included groups:
Excluded groups:

69 | (Hover the method name to see the test class name)

70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 |
PASSED TESTS
Test methodExceptionTime (seconds)Instance
test
Test class: testScripts.Test1
0testScripts.Test1@14bf9759

83 | 84 | -------------------------------------------------------------------------------- /test-output/junitreports/TEST-testScripts.TestNG.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | screenshot 5 | screenshot 6 | 0.0.1-SNAPSHOT 7 | screenshot 8 | Sample to integrate screenshots with TestNG reports and Selenium 9 | 10 | 11 | 12 | 13 | org.apache.maven.plugins 14 | maven-compiler-plugin 15 | 16 | 3.8.0 17 | 1.8 18 | 19 | 20 | 21 | org.apache.maven.plugins 22 | maven-surefire-plugin 23 | 3.0.0 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.testng 32 | testng 33 | 6.14.3 34 | test 35 | 36 | 37 | 38 | io.appium 39 | java-client 40 | 7.0.0 41 | 42 | 43 | 44 | org.seleniumhq.selenium 45 | selenium-server 46 | 3.141.59 47 | 48 | 49 | 50 | org.seleniumhq.selenium 51 | selenium-java 52 | 3.141.59 53 | 54 | 55 | 56 | org.seleniumhq.selenium 57 | selenium-api 58 | 3.141.59 59 | 60 | 61 | org.apache.httpcomponents 62 | httpclient 63 | 4.5.6 64 | 65 | 66 | 67 | com.jayway.jsonpath 68 | json-path 69 | 2.4.0 70 | 71 | 72 | 73 | org.apache.poi 74 | poi 75 | 4.0.1 76 | 77 | 78 | 79 | org.apache.poi 80 | poi-ooxml 81 | 4.0.1 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /test-output/junitreports/TEST-testScripts.TestMedia.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /test-output/junitreports/TEST-testScripts.TestExcel.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/utility/TestListener.java: -------------------------------------------------------------------------------- 1 | package utility; 2 | 3 | import java.io.File; 4 | 5 | import org.openqa.selenium.Capabilities; 6 | import org.openqa.selenium.WebDriver; 7 | import org.openqa.selenium.remote.RemoteWebDriver; 8 | import org.testng.ITestContext; 9 | import org.testng.ITestListener; 10 | import org.testng.ITestResult; 11 | import org.testng.Reporter; 12 | 13 | public class TestListener implements ITestListener { 14 | 15 | @Override // Get screenshot before start of test 16 | public void onTestStart(ITestResult result) { 17 | try { 18 | Screenshot.getScreenshot(Platform.getDriver(), result.getName() + "_START"); 19 | } catch (Exception e) { 20 | Reporter.log("listener onTestStart fail"); 21 | e.printStackTrace(); 22 | } 23 | 24 | } 25 | 26 | @Override // Log screenshot at test success 27 | public void onTestSuccess(ITestResult result) { 28 | File screenshot; 29 | try { 30 | screenshot = Screenshot.getScreenshot(Platform.getDriver(), result.getName() + "_SUCCESS"); 31 | Reporter.log("Result status: " + result.getStatus()); 32 | Screenshot.logScreenshot(screenshot); 33 | } catch (Exception e) { 34 | Reporter.log("listener onTestSuccess fail"); 35 | e.printStackTrace(); 36 | } 37 | 38 | } 39 | 40 | @Override // Log screenshot at test failure 41 | public void onTestFailure(ITestResult result) { 42 | File screenshot; 43 | try { 44 | screenshot = Screenshot.getScreenshot(Platform.getDriver(), result.getName() + "_FAILURE"); 45 | Reporter.log("Result status: " + result.getStatus()); 46 | Screenshot.logScreenshot(screenshot); 47 | } catch (Exception e) { 48 | Reporter.log("listener onTestFailure fail"); 49 | e.printStackTrace(); 50 | } 51 | 52 | } 53 | 54 | @Override // Log screenshot at test skip 55 | public void onTestSkipped(ITestResult result) { 56 | File screenshot; 57 | try { 58 | screenshot = Screenshot.getScreenshot(Platform.getDriver(), result.getName() + "_SKIP"); 59 | Reporter.log("Result status: " + result.getStatus()); 60 | Screenshot.logScreenshot(screenshot); 61 | } catch (Exception e) { 62 | Reporter.log("listener onTestSkipped fail"); 63 | e.printStackTrace(); 64 | } 65 | 66 | } 67 | 68 | @Override 69 | public void onTestFailedButWithinSuccessPercentage(ITestResult result) { 70 | // TODO Auto-generated method stub 71 | } 72 | 73 | @Override // Print browser name in console on start 74 | public void onStart(ITestContext context) { 75 | WebDriver driver = Platform.getDriver(); 76 | Capabilities caps = ((RemoteWebDriver) driver).getCapabilities(); 77 | System.out.println("browser: " + caps.getBrowserName()); 78 | } 79 | 80 | @Override 81 | public void onFinish(ITestContext context) { 82 | // TODO Auto-generated method stub 83 | 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /test-output/junitreports/TEST-testScripts.TestScreenshot.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/utility/ExcelExportAndFileIO.java: -------------------------------------------------------------------------------- 1 | package utility; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | 7 | import org.apache.poi.ss.usermodel.Workbook; 8 | import org.apache.poi.hssf.usermodel.HSSFWorkbook; 9 | import org.apache.poi.ss.usermodel.Cell; 10 | import org.apache.poi.ss.usermodel.Row; 11 | import org.apache.poi.ss.usermodel.Sheet; 12 | import org.apache.poi.xssf.usermodel.XSSFWorkbook; 13 | import org.testng.Assert; 14 | 15 | public class ExcelExportAndFileIO { 16 | 17 | private static String EXCEL_FOLDER_PATH = System.getProperty("user.dir") + "/Excel/"; 18 | 19 | public static void writeExcel(String fileName, String sheetName, String[] dataToWrite) throws Exception { 20 | // Create file input stream 21 | File file = new File(EXCEL_FOLDER_PATH + fileName); 22 | FileInputStream inputStream = new FileInputStream(file); 23 | 24 | // Get extension of excel file 25 | String fileExt = fileName.substring(fileName.indexOf(".")); 26 | 27 | // initialize workbook on the basis of excel file extension 28 | Workbook workbook = null; 29 | switch (fileExt) { 30 | case ".xlsx": 31 | workbook = new XSSFWorkbook(inputStream); 32 | break; 33 | case ".xls": 34 | workbook = new HSSFWorkbook(inputStream); 35 | break; 36 | default: 37 | Assert.fail("Invalid file extension: " + fileExt); 38 | } 39 | 40 | // Initialize sheet 41 | Sheet sheet = workbook.getSheet(sheetName); 42 | 43 | // Get number of rows 44 | int rowCount = sheet.getLastRowNum() - sheet.getFirstRowNum(); 45 | 46 | // Create new row to write data 47 | Row newRow = sheet.createRow(rowCount + 1); 48 | 49 | // Create cells and write data 50 | for (int i = 0; i < dataToWrite.length; ++i) { 51 | Cell cell = newRow.createCell(i); 52 | cell.setCellValue(dataToWrite[i]); 53 | } 54 | 55 | inputStream.close(); // close input stream 56 | 57 | // Create output stream and write in file 58 | FileOutputStream outputStream = new FileOutputStream(file); 59 | workbook.write(outputStream); 60 | 61 | outputStream.close(); // close output stream 62 | } 63 | 64 | public static void readExcel(String fileName, String sheetName) throws Exception { 65 | // Create file input stream 66 | File file = new File(EXCEL_FOLDER_PATH + fileName); 67 | FileInputStream inputStream = new FileInputStream(file); 68 | 69 | // Get extension of excel file 70 | String fileExt = fileName.substring(fileName.indexOf(".")); 71 | 72 | // initialize workbook on the basis of excel file extension 73 | Workbook workbook = null; 74 | switch (fileExt) { 75 | case ".xlsx": 76 | workbook = new XSSFWorkbook(inputStream); 77 | break; 78 | case ".xls": 79 | workbook = new HSSFWorkbook(inputStream); 80 | break; 81 | default: 82 | Assert.fail("Invalid file extension: " + fileExt); 83 | 84 | } 85 | 86 | // Initialize sheet 87 | Sheet sheet = workbook.getSheet(sheetName); 88 | 89 | // Get number of rows 90 | int physicalRowCount = sheet.getPhysicalNumberOfRows(); 91 | 92 | // Read data and print on console 93 | for (int i = 0; i < physicalRowCount; ++i) { 94 | Row row = sheet.getRow(i); 95 | for (int j = 0; j < row.getLastCellNum(); ++j) { 96 | System.out.print(row.getCell(j).getStringCellValue() + "||"); 97 | } 98 | 99 | System.out.println(); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /test-output/emailable-report.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | TestNG Report 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
Test# Passed# Skipped# FailedTime (ms)Included GroupsExcluded Groups
TestNGSuite
Test1114,085
14 | 15 |
ClassMethodStartTime (ms)
TestNGSuite
Test — failed
testScripts.TestScreenshottestFail1551635957272587
Test — skipped
testScripts.TestScreenshottestSkip15516359583620
Test — passed
testScripts.TestScreenshottestPass15516359547862011
16 |

Test

testScripts.TestScreenshot#testFail

Messages
Result status: 2
Exception
java.lang.AssertionError: null 17 | at testScripts.TestScreenshot.testFail(TestScreenshot.java:37) 18 | ... Removed 27 stack frames

back to summary

19 |

testScripts.TestScreenshot#testSkip

Messages
Result status: 3
Exception
java.lang.Throwable: Method TestScreenshot.testSkip()[pri:0, instance:testScripts.TestScreenshot@306cf3ea] depends on not successfully finished methods 20 | ... Removed 18 stack frames

back to summary

21 |

testScripts.TestScreenshot#testPass

Messages
Result status: 1

back to summary

22 | 23 | 24 | -------------------------------------------------------------------------------- /test-output/testng-reports.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | $('a.navigator-link').click(function() { 3 | // Extract the panel for this link 4 | var panel = getPanelName($(this)); 5 | 6 | // Mark this link as currently selected 7 | $('.navigator-link').parent().removeClass('navigator-selected'); 8 | $(this).parent().addClass('navigator-selected'); 9 | 10 | showPanel(panel); 11 | }); 12 | 13 | installMethodHandlers('failed'); 14 | installMethodHandlers('skipped'); 15 | installMethodHandlers('passed', true); // hide passed methods by default 16 | 17 | $('a.method').click(function() { 18 | showMethod($(this)); 19 | return false; 20 | }); 21 | 22 | // Hide all the panels and display the first one (do this last 23 | // to make sure the click() will invoke the listeners) 24 | $('.panel').hide(); 25 | $('.navigator-link').first().click(); 26 | 27 | // Collapse/expand the suites 28 | $('a.collapse-all-link').click(function() { 29 | var contents = $('.navigator-suite-content'); 30 | if (contents.css('display') == 'none') { 31 | contents.show(); 32 | } else { 33 | contents.hide(); 34 | } 35 | }); 36 | }); 37 | 38 | // The handlers that take care of showing/hiding the methods 39 | function installMethodHandlers(name, hide) { 40 | function getContent(t) { 41 | return $('.method-list-content.' + name + "." + t.attr('panel-name')); 42 | } 43 | 44 | function getHideLink(t, name) { 45 | var s = 'a.hide-methods.' + name + "." + t.attr('panel-name'); 46 | return $(s); 47 | } 48 | 49 | function getShowLink(t, name) { 50 | return $('a.show-methods.' + name + "." + t.attr('panel-name')); 51 | } 52 | 53 | function getMethodPanelClassSel(element, name) { 54 | var panelName = getPanelName(element); 55 | var sel = '.' + panelName + "-class-" + name; 56 | return $(sel); 57 | } 58 | 59 | $('a.hide-methods.' + name).click(function() { 60 | var w = getContent($(this)); 61 | w.hide(); 62 | getHideLink($(this), name).hide(); 63 | getShowLink($(this), name).show(); 64 | getMethodPanelClassSel($(this), name).hide(); 65 | }); 66 | 67 | $('a.show-methods.' + name).click(function() { 68 | var w = getContent($(this)); 69 | w.show(); 70 | getHideLink($(this), name).show(); 71 | getShowLink($(this), name).hide(); 72 | showPanel(getPanelName($(this))); 73 | getMethodPanelClassSel($(this), name).show(); 74 | }); 75 | 76 | if (hide) { 77 | $('a.hide-methods.' + name).click(); 78 | } else { 79 | $('a.show-methods.' + name).click(); 80 | } 81 | } 82 | 83 | function getHashForMethod(element) { 84 | return element.attr('hash-for-method'); 85 | } 86 | 87 | function getPanelName(element) { 88 | return element.attr('panel-name'); 89 | } 90 | 91 | function showPanel(panelName) { 92 | $('.panel').hide(); 93 | var panel = $('.panel[panel-name="' + panelName + '"]'); 94 | panel.show(); 95 | } 96 | 97 | function showMethod(element) { 98 | var hashTag = getHashForMethod(element); 99 | var panelName = getPanelName(element); 100 | showPanel(panelName); 101 | var current = document.location.href; 102 | var base = current.substring(0, current.indexOf('#')) 103 | document.location.href = base + '#' + hashTag; 104 | var newPosition = $(document).scrollTop() - 65; 105 | $(document).scrollTop(newPosition); 106 | } 107 | 108 | function drawTable() { 109 | for (var i = 0; i < suiteTableInitFunctions.length; i++) { 110 | window[suiteTableInitFunctions[i]](); 111 | } 112 | 113 | for (var k in window.suiteTableData) { 114 | var v = window.suiteTableData[k]; 115 | var div = v.tableDiv; 116 | var data = v.tableData 117 | var table = new google.visualization.Table(document.getElementById(div)); 118 | table.draw(data, { 119 | showRowNumber : false 120 | }); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/utility/MediaLibrary.java: -------------------------------------------------------------------------------- 1 | package utility; 2 | 3 | import org.openqa.selenium.JavascriptExecutor; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.interactions.Actions; 6 | import org.testng.Assert; 7 | 8 | public class MediaLibrary { 9 | 10 | public static void playMedia(WebDriver driver, String media, int index) throws Exception { 11 | 12 | // Focus browser to handle promise rejection 13 | focusBrowser(driver); 14 | 15 | // Wait for buffering if media is video 16 | if (media.equals("video")) { 17 | waitForVideoBuffering(driver, index); 18 | } 19 | 20 | JavascriptExecutor js = (JavascriptExecutor) driver; 21 | 22 | // Get current time before playing media 23 | long mediaTimePre = (long) js 24 | .executeScript("return document.getElementsByTagName('" + media + "')[" + index + "].currentTime"); 25 | 26 | // Get state of media 27 | boolean isPaused = (boolean) js 28 | .executeScript("return document.getElementsByTagName('" + media + "')[" + index + "].paused"); 29 | 30 | // Play media if media is not already playing 31 | if (isPaused) { 32 | js.executeScript("document.getElementsByTagName('" + media + "')[" + index 33 | + "].play().then(() => { console.log('play') })"); 34 | } else { 35 | throw new Exception("In playMedia(): Media already playing"); 36 | } 37 | 38 | // Wait for media to be ready to load all frames 39 | waitForMediaToBeReady(driver, index, media); 40 | 41 | // Wait for 1000 ms 42 | Thread.sleep(1000); 43 | 44 | // Get current time after playing media 45 | double mediaTimePost = (double) ((JavascriptExecutor) driver) 46 | .executeScript("return document.getElementsByTagName('" + media + "')[" + index + "].currentTime"); 47 | 48 | // Assert that media is playing 49 | Assert.assertTrue(mediaTimePost > mediaTimePre); 50 | } 51 | 52 | public static void pauseMedia(WebDriver driver, String media, int index) throws Exception { 53 | 54 | // Focus browser to handle promise rejection 55 | focusBrowser(driver); 56 | 57 | JavascriptExecutor js = (JavascriptExecutor) driver; 58 | 59 | // Get state of media 60 | boolean isPaused = (boolean) js 61 | .executeScript("return document.getElementsByTagName('" + media + "')[" + index + "].paused"); 62 | 63 | // Pause media if not already paused 64 | if (!isPaused) { 65 | js.executeScript("document.getElementsByTagName('" + media + "')[" + index + "].pause()"); 66 | } else { 67 | throw new Exception("In pauseMedia(): Media already paused"); 68 | } 69 | 70 | // Get current time after pause 71 | double mediaTimePre = (double) js 72 | .executeScript("return document.getElementsByTagName('" + media + "')[" + index + "].currentTime"); 73 | 74 | // Wait for 1000 ms 75 | Thread.sleep(1000); 76 | 77 | // Again Get current time 78 | double mediaTimePost = (double) ((JavascriptExecutor) driver) 79 | .executeScript("return document.getElementsByTagName('" + media + "')[" + index + "].currentTime"); 80 | 81 | // Assert if media is paused 82 | Assert.assertTrue(mediaTimePost == mediaTimePre); 83 | } 84 | 85 | private static void focusBrowser(WebDriver driver) { 86 | // Click on 0,0 to handle promise rejection thrown by browser on play()/pause() 87 | // I can't find any other work around 88 | // Please help if you find anything else 89 | Actions tap = new Actions(driver); 90 | tap.moveByOffset(0, 0).click().build().perform(); 91 | } 92 | 93 | private static void waitForVideoBuffering(WebDriver driver, int index) throws Exception { 94 | 95 | JavascriptExecutor js = (JavascriptExecutor) driver; 96 | 97 | long readyState = 0; 98 | long startTime = System.currentTimeMillis(); 99 | while (System.currentTimeMillis() - startTime < 20000) { 100 | readyState = (long) js 101 | .executeScript("return document.getElementsByTagName('video')[" + index + "].readyState"); 102 | if (readyState > 0) 103 | return; 104 | } 105 | 106 | throw new Exception("In waitForVideoBuffering: Time Out (20 seconds) for video buffering state"); 107 | } 108 | 109 | private static void waitForMediaToBeReady(WebDriver driver, int index, String media) throws Exception { 110 | JavascriptExecutor js = (JavascriptExecutor) driver; 111 | 112 | long readyState = 0; 113 | long startTime = System.currentTimeMillis(); 114 | while (System.currentTimeMillis() - startTime < 20000) { 115 | readyState = (long) js 116 | .executeScript("return document.getElementsByTagName('" + media + "')[" + index + "].readyState"); 117 | if (readyState > 2) 118 | return; 119 | } 120 | 121 | throw new Exception("In waitForMediaToBeReady: Time Out (20 seconds) for media ready state"); 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /src/utility/Screenshot.java: -------------------------------------------------------------------------------- 1 | package utility; 2 | 3 | import java.awt.image.BufferedImage; 4 | import java.awt.image.DataBuffer; 5 | import java.io.File; 6 | import java.text.SimpleDateFormat; 7 | import java.util.Calendar; 8 | 9 | import javax.imageio.ImageIO; 10 | 11 | import org.apache.commons.io.FileUtils; 12 | import org.openqa.selenium.Dimension; 13 | import org.openqa.selenium.JavascriptExecutor; 14 | import org.openqa.selenium.OutputType; 15 | import org.openqa.selenium.Point; 16 | import org.openqa.selenium.TakesScreenshot; 17 | import org.openqa.selenium.WebDriver; 18 | import org.openqa.selenium.WebElement; 19 | import org.testng.Reporter; 20 | 21 | public class Screenshot { 22 | 23 | private static String SCREENSHOT_FOLDER_PATH = System.getProperty("user.dir") + "/Screenshots/"; 24 | 25 | // Method to take screenshot of element 26 | public static File getScreenshotOfElement(WebDriver driver, WebElement element, String fileName) throws Exception { 27 | 28 | // Get DPR 29 | JavascriptExecutor js = (JavascriptExecutor) driver; 30 | long dpr = (long) js.executeScript("return (window.devicePixelRatio)"); 31 | 32 | // Calculate physical size of the element to be cropped 33 | Dimension eleSize = element.getSize(); 34 | int imageWidth = (int) (eleSize.getWidth() * dpr); 35 | int imageHeight = (int) (eleSize.getHeight() * dpr); 36 | Dimension physicalSize = new Dimension(imageWidth, imageHeight); 37 | 38 | // Calculate physical location of element to be cropped 39 | Point eleLoc = element.getLocation(); 40 | int imageX = (int) (eleLoc.getX() * dpr); 41 | int imageY = (int) (eleLoc.getY() * dpr); 42 | Point physicalLoc = new Point(imageX, imageY); 43 | 44 | // Get entire page screenshot 45 | File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); 46 | 47 | // Return cropped screenshot with time stamp in name 48 | return cropImage(screenshot, physicalLoc, physicalSize, fileName); 49 | 50 | } 51 | 52 | // Method to take screenshot of element in frame 53 | public static File getScreenshotOfElementInFrame(WebDriver driver, WebElement frame, WebElement element, 54 | String fileName) throws Exception { 55 | // Switch to frame and get location and size of element 56 | driver.switchTo().frame(frame); 57 | 58 | Point eleLoc = element.getLocation(); 59 | Dimension eleSize = element.getSize(); 60 | 61 | driver.switchTo().defaultContent(); 62 | 63 | // Get DPR of device screen 64 | JavascriptExecutor js = (JavascriptExecutor) driver; 65 | long dpr = (long) js.executeScript("return (window.devicePixelRatio)"); 66 | 67 | // Calculate physical size of the element to be cropped 68 | int imageWidth = (int) (eleSize.getWidth() * dpr); 69 | int imageHeight = (int) (eleSize.getHeight() * dpr); 70 | Dimension physicalSize = new Dimension(imageWidth, imageHeight); 71 | 72 | // Calculate offset for location of element to be cropped 73 | Point framePosition = frame.getLocation(); 74 | 75 | long offsetX = framePosition.getX() + 10; 76 | long offsetY = framePosition.getY() + 10; 77 | 78 | // Calculate physical location of the element to be cropped 79 | int imageX = (int) ((eleLoc.getX() + offsetX) * dpr); 80 | int imageY = (int) ((eleLoc.getY() + offsetY) * dpr); 81 | Point physicalLoc = new Point(imageX, imageY); 82 | 83 | // Get entire page screenshot 84 | File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); 85 | 86 | // Return cropped screenshot with time stamp in name 87 | return cropImage(screenshot, physicalLoc, physicalSize, fileName); 88 | 89 | } 90 | 91 | // Method to crop image 92 | private static File cropImage(File image, Point location, Dimension size, String fileName) throws Exception { 93 | 94 | BufferedImage fullImage = ImageIO.read(image); 95 | 96 | // Crop the screenshot to given size and location 97 | BufferedImage croppedImg = fullImage.getSubimage(location.getX(), location.getY(), size.getWidth(), 98 | size.getHeight()); 99 | ImageIO.write(croppedImg, "png", image); 100 | 101 | // Save screenshot with time stamp in name 102 | String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime()); 103 | 104 | File croppedImage = new File(SCREENSHOT_FOLDER_PATH + fileName + "_" + timeStamp + ".png"); 105 | FileUtils.copyFile(image, croppedImage); 106 | 107 | return croppedImage; 108 | } 109 | 110 | // Method to get screenshot of page 111 | public static File getScreenshot(WebDriver driver, String fileName) throws Exception { 112 | 113 | // Get entire page screenshot 114 | File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); 115 | 116 | // Save screenshot with time stamp in name 117 | String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime()); 118 | 119 | File screenshotName = new File(SCREENSHOT_FOLDER_PATH + fileName + "_" + timeStamp + ".png"); 120 | FileUtils.copyFile(screenshot, screenshotName); 121 | 122 | return screenshotName; 123 | } 124 | 125 | // Method to compare image 126 | public static boolean isImageSame(File image1, File image2) throws Exception { 127 | 128 | // Get data of image1 129 | BufferedImage bufferImage1 = ImageIO.read(image1); 130 | DataBuffer dataImage1 = bufferImage1.getData().getDataBuffer(); 131 | int sizefileInput = dataImage1.getSize(); 132 | 133 | // Get data of image2 134 | BufferedImage bufferImage2 = ImageIO.read(image2); 135 | DataBuffer dataImage2 = bufferImage2.getData().getDataBuffer(); 136 | int sizefileOutPut = dataImage2.getSize(); 137 | 138 | // Compare data of image1 and image2 139 | boolean matchFlag = true; 140 | if (sizefileInput == sizefileOutPut) { 141 | for (int i = 0; i < sizefileInput; i++) { 142 | if (dataImage1.getElem(i) != dataImage2.getElem(i)) { 143 | return matchFlag = false; 144 | } 145 | } 146 | } else { 147 | return matchFlag = false; 148 | } 149 | return matchFlag; 150 | } 151 | 152 | public static void logScreenshot(File screenshot) throws Exception { 153 | // Get path of screenshot and log it to TestNG report 154 | String filePath = screenshot.toString(); 155 | Reporter.log(" "); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /test-output/testng-reports.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0px 0px 5px 5px; 3 | } 4 | 5 | ul { 6 | margin: 0px; 7 | } 8 | 9 | li { 10 | list-style-type: none; 11 | } 12 | 13 | a { 14 | text-decoration: none; 15 | } 16 | 17 | a:hover { 18 | text-decoration: underline; 19 | } 20 | 21 | .navigator-selected { 22 | background: #ffa500; 23 | } 24 | 25 | .wrapper { 26 | position: absolute; 27 | top: 60px; 28 | bottom: 0; 29 | left: 400px; 30 | right: 0; 31 | overflow: auto; 32 | } 33 | 34 | .navigator-root { 35 | position: absolute; 36 | top: 60px; 37 | bottom: 0; 38 | left: 0; 39 | width: 400px; 40 | overflow-y: auto; 41 | } 42 | 43 | .suite { 44 | margin: 0px 10px 10px 0px; 45 | background-color: #fff8dc; 46 | } 47 | 48 | .suite-name { 49 | padding-left: 10px; 50 | font-size: 25px; 51 | font-family: Times; 52 | } 53 | 54 | .main-panel-header { 55 | padding: 5px; 56 | background-color: #9FB4D9; //afeeee; 57 | font-family: monospace; 58 | font-size: 18px; 59 | } 60 | 61 | .main-panel-content { 62 | padding: 5px; 63 | margin-bottom: 10px; 64 | background-color: #DEE8FC; //d0ffff; 65 | } 66 | 67 | .rounded-window { 68 | border-radius: 10px; 69 | border-style: solid; 70 | border-width: 1px; 71 | } 72 | 73 | .rounded-window-top { 74 | border-top-right-radius: 10px 10px; 75 | border-top-left-radius: 10px 10px; 76 | border-style: solid; 77 | border-width: 1px; 78 | overflow: auto; 79 | } 80 | 81 | .light-rounded-window-top { 82 | border-top-right-radius: 10px 10px; 83 | border-top-left-radius: 10px 10px; 84 | } 85 | 86 | .rounded-window-bottom { 87 | border-style: solid; 88 | border-width: 0px 1px 1px 1px; 89 | border-bottom-right-radius: 10px 10px; 90 | border-bottom-left-radius: 10px 10px; 91 | overflow: auto; 92 | } 93 | 94 | .method-name { 95 | font-size: 12px; 96 | font-family: monospace; 97 | } 98 | 99 | .method-content { 100 | border-style: solid; 101 | border-width: 0px 0px 1px 0px; 102 | margin-bottom: 10; 103 | padding-bottom: 5px; 104 | width: 80%; 105 | } 106 | 107 | .parameters { 108 | font-size: 14px; 109 | font-family: monospace; 110 | } 111 | 112 | .stack-trace { 113 | white-space: pre; 114 | font-family: monospace; 115 | font-size: 12px; 116 | font-weight: bold; 117 | margin-top: 0px; 118 | margin-left: 20px; 119 | } 120 | 121 | .testng-xml { 122 | font-family: monospace; 123 | } 124 | 125 | .method-list-content { 126 | margin-left: 10px; 127 | } 128 | 129 | .navigator-suite-content { 130 | margin-left: 10px; 131 | font: 12px 'Lucida Grande'; 132 | } 133 | 134 | .suite-section-title { 135 | margin-top: 10px; 136 | width: 80%; 137 | border-style: solid; 138 | border-width: 1px 0px 0px 0px; 139 | font-family: Times; 140 | font-size: 18px; 141 | font-weight: bold; 142 | } 143 | 144 | .suite-section-content { 145 | list-style-image: url(bullet_point.png); 146 | } 147 | 148 | .top-banner-root { 149 | position: absolute; 150 | top: 0; 151 | height: 45px; 152 | left: 0; 153 | right: 0; 154 | padding: 5px; 155 | margin: 0px 0px 5px 0px; 156 | background-color: #0066ff; 157 | font-family: Times; 158 | color: #fff; 159 | text-align: center; 160 | } 161 | 162 | .top-banner-title-font { 163 | font-size: 25px; 164 | } 165 | 166 | .test-name { 167 | font-family: 'Lucida Grande'; 168 | font-size: 16px; 169 | } 170 | 171 | .suite-icon { 172 | padding: 5px; 173 | float: right; 174 | height: 20; 175 | } 176 | 177 | .test-group { 178 | font: 20px 'Lucida Grande'; 179 | margin: 5px 5px 10px 5px; 180 | border-width: 0px 0px 1px 0px; 181 | border-style: solid; 182 | padding: 5px; 183 | } 184 | 185 | .test-group-name { 186 | font-weight: bold; 187 | } 188 | 189 | .method-in-group { 190 | font-size: 16px; 191 | margin-left: 80px; 192 | } 193 | 194 | table.google-visualization-table-table { 195 | width: 100%; 196 | } 197 | 198 | .reporter-method-name { 199 | font-size: 14px; 200 | font-family: monospace; 201 | } 202 | 203 | .reporter-method-output-div { 204 | padding: 5px; 205 | margin: 0px 0px 5px 20px; 206 | font-size: 12px; 207 | font-family: monospace; 208 | border-width: 0px 0px 0px 1px; 209 | border-style: solid; 210 | } 211 | 212 | .ignored-class-div { 213 | font-size: 14px; 214 | font-family: monospace; 215 | } 216 | 217 | .ignored-methods-div { 218 | padding: 5px; 219 | margin: 0px 0px 5px 20px; 220 | font-size: 12px; 221 | font-family: monospace; 222 | border-width: 0px 0px 0px 1px; 223 | border-style: solid; 224 | } 225 | 226 | .border-failed { 227 | border-top-left-radius: 10px 10px; 228 | border-bottom-left-radius: 10px 10px; 229 | border-style: solid; 230 | border-width: 0px 0px 0px 10px; 231 | border-color: #f00; 232 | } 233 | 234 | .border-skipped { 235 | border-top-left-radius: 10px 10px; 236 | border-bottom-left-radius: 10px 10px; 237 | border-style: solid; 238 | border-width: 0px 0px 0px 10px; 239 | border-color: #edc600; 240 | } 241 | 242 | .border-passed { 243 | border-top-left-radius: 10px 10px; 244 | border-bottom-left-radius: 10px 10px; 245 | border-style: solid; 246 | border-width: 0px 0px 0px 10px; 247 | border-color: #19f52d; 248 | } 249 | 250 | .times-div { 251 | text-align: center; 252 | padding: 5px; 253 | } 254 | 255 | .suite-total-time { 256 | font: 16px 'Lucida Grande'; 257 | } 258 | 259 | .configuration-suite { 260 | margin-left: 20px; 261 | } 262 | 263 | .configuration-test { 264 | margin-left: 40px; 265 | } 266 | 267 | .configuration-class { 268 | margin-left: 60px; 269 | } 270 | 271 | .configuration-method { 272 | margin-left: 80px; 273 | } 274 | 275 | .test-method { 276 | margin-left: 100px; 277 | } 278 | 279 | .chronological-class { 280 | background-color: #0ccff; 281 | border-style: solid; 282 | border-width: 0px 0px 1px 1px; 283 | } 284 | 285 | .method-start { 286 | float: right; 287 | } 288 | 289 | .chronological-class-name { 290 | padding: 0px 0px 0px 5px; 291 | color: #008; 292 | } 293 | 294 | .after, .before, .test-method { 295 | font-family: monospace; 296 | font-size: 14px; 297 | } 298 | 299 | .navigator-suite-header { 300 | font-size: 22px; 301 | margin: 0px 10px 5px 0px; 302 | background-color: #deb887; 303 | text-align: center; 304 | } 305 | 306 | .collapse-all-icon { 307 | padding: 5px; 308 | float: right; 309 | } 310 | -------------------------------------------------------------------------------- /test-output/TestNGSuite/Test1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | TestNG: Test1 4 | 5 | 6 | 7 | 11 | 53 | 54 | 55 | 56 |

Test1

57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
Tests passed/Failed/Skipped:1/1/1
Started on:Tue Jan 08 14:43:14 IST 2019
Total time:8 seconds (8084 ms)
Included groups:
Excluded groups:

69 | (Hover the method name to see the test class name)

70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 87 | 120 | 121 | 122 |
FAILED TESTS
Test methodExceptionTime (seconds)Instance
testFail
Test class: testScripts.TestNG
79 | Show output 80 | 81 | Show all outputs 82 |
83 | Result status: 2
84 |
85 |
86 |
java.lang.AssertionError: null
 88 | 	at testScripts.TestNG.testFail(TestNG.java:22)
 89 | ... Removed 27 stack frames
Click to show all stack frames 90 |
java.lang.AssertionError: null
 91 | 	at org.testng.Assert.fail(Assert.java:96)
 92 | 	at org.testng.Assert.fail(Assert.java:103)
 93 | 	at testScripts.TestNG.testFail(TestNG.java:22)
 94 | 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 95 | 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 96 | 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 97 | 	at java.lang.reflect.Method.invoke(Method.java:498)
 98 | 	at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
 99 | 	at org.testng.internal.Invoker.invokeMethod(Invoker.java:580)
100 | 	at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:716)
101 | 	at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:988)
102 | 	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
103 | 	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
104 | 	at org.testng.TestRunner.privateRun(TestRunner.java:648)
105 | 	at org.testng.TestRunner.run(TestRunner.java:505)
106 | 	at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
107 | 	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
108 | 	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
109 | 	at org.testng.SuiteRunner.run(SuiteRunner.java:364)
110 | 	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
111 | 	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
112 | 	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
113 | 	at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
114 | 	at org.testng.TestNG.runSuites(TestNG.java:1049)
115 | 	at org.testng.TestNG.run(TestNG.java:1017)
116 | 	at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114)
117 | 	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
118 | 	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
119 | 
0testScripts.TestNG@5f2108b5

123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 140 | 141 | 142 | 143 |
PASSED TESTS
Test methodExceptionTime (seconds)Instance
testPass
Test class: testScripts.TestNG
132 | Show output 133 | 134 | Show all outputs 135 |
136 | Result status: 1
137 |
138 |
139 |
7testScripts.TestNG@5f2108b5

144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 161 | 183 | 184 | 185 |
SKIPPED TESTS
Test methodExceptionTime (seconds)Instance
testSkip
Test class: testScripts.TestNG
153 | Show output 154 | 155 | Show all outputs 156 |
157 | Result status: 3
158 |
159 |
160 |
java.lang.Throwable: Method TestNG.testSkip()[pri:0, instance:testScripts.TestNG@5f2108b5] depends on not successfully finished methods
162 | ... Removed 18 stack frames
Click to show all stack frames 163 |
java.lang.Throwable: Method TestNG.testSkip()[pri:0, instance:testScripts.TestNG@5f2108b5] depends on not successfully finished methods
164 | 	at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:887)
165 | 	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
166 | 	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
167 | 	at org.testng.TestRunner.privateRun(TestRunner.java:648)
168 | 	at org.testng.TestRunner.run(TestRunner.java:505)
169 | 	at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
170 | 	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
171 | 	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
172 | 	at org.testng.SuiteRunner.run(SuiteRunner.java:364)
173 | 	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
174 | 	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
175 | 	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
176 | 	at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
177 | 	at org.testng.TestNG.runSuites(TestNG.java:1049)
178 | 	at org.testng.TestNG.run(TestNG.java:1017)
179 | 	at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114)
180 | 	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
181 | 	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
182 | 
0null

186 | 187 | -------------------------------------------------------------------------------- /test-output/testng-results.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ]]> 9 | 10 | 11 | 12 | 13 | 14 | ]]> 15 | 16 | 17 | 18 | 19 | 20 | ]]> 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | ]]> 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | ]]> 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | ]]> 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /test-output/TestNGSuite/Test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | TestNG: Test 4 | 5 | 6 | 7 | 11 | 53 | 54 | 55 | 56 |

Test

57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
Tests passed/Failed/Skipped:1/1/1
Started on:Sun Mar 03 23:29:14 IST 2019
Total time:4 seconds (4085 ms)
Included groups:
Excluded groups:

69 | (Hover the method name to see the test class name)

70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 87 | 120 | 121 | 122 |
FAILED TESTS
Test methodExceptionTime (seconds)Instance
testFail
Test class: testScripts.TestScreenshot
79 | Show output 80 | 81 | Show all outputs 82 |
83 | Result status: 2
84 |
85 |
86 |
java.lang.AssertionError: null
 88 | 	at testScripts.TestScreenshot.testFail(TestScreenshot.java:37)
 89 | ... Removed 27 stack frames
Click to show all stack frames 90 |
java.lang.AssertionError: null
 91 | 	at org.testng.Assert.fail(Assert.java:96)
 92 | 	at org.testng.Assert.fail(Assert.java:103)
 93 | 	at testScripts.TestScreenshot.testFail(TestScreenshot.java:37)
 94 | 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 95 | 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 96 | 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 97 | 	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
 98 | 	at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
 99 | 	at org.testng.internal.Invoker.invokeMethod(Invoker.java:580)
100 | 	at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:716)
101 | 	at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:988)
102 | 	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
103 | 	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
104 | 	at org.testng.TestRunner.privateRun(TestRunner.java:648)
105 | 	at org.testng.TestRunner.run(TestRunner.java:505)
106 | 	at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
107 | 	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
108 | 	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
109 | 	at org.testng.SuiteRunner.run(SuiteRunner.java:364)
110 | 	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
111 | 	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
112 | 	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
113 | 	at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
114 | 	at org.testng.TestNG.runSuites(TestNG.java:1049)
115 | 	at org.testng.TestNG.run(TestNG.java:1017)
116 | 	at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114)
117 | 	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
118 | 	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
119 | 
0testScripts.TestScreenshot@306cf3ea

123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 140 | 141 | 142 | 143 |
PASSED TESTS
Test methodExceptionTime (seconds)Instance
testPass
Test class: testScripts.TestScreenshot
132 | Show output 133 | 134 | Show all outputs 135 |
136 | Result status: 1
137 |
138 |
139 |
2testScripts.TestScreenshot@306cf3ea

144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 161 | 183 | 184 | 185 |
SKIPPED TESTS
Test methodExceptionTime (seconds)Instance
testSkip
Test class: testScripts.TestScreenshot
153 | Show output 154 | 155 | Show all outputs 156 |
157 | Result status: 3
158 |
159 |
160 |
java.lang.Throwable: Method TestScreenshot.testSkip()[pri:0, instance:testScripts.TestScreenshot@306cf3ea] depends on not successfully finished methods
162 | ... Removed 18 stack frames
Click to show all stack frames 163 |
java.lang.Throwable: Method TestScreenshot.testSkip()[pri:0, instance:testScripts.TestScreenshot@306cf3ea] depends on not successfully finished methods
164 | 	at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:887)
165 | 	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
166 | 	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
167 | 	at org.testng.TestRunner.privateRun(TestRunner.java:648)
168 | 	at org.testng.TestRunner.run(TestRunner.java:505)
169 | 	at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
170 | 	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
171 | 	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
172 | 	at org.testng.SuiteRunner.run(SuiteRunner.java:364)
173 | 	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
174 | 	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
175 | 	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
176 | 	at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
177 | 	at org.testng.TestNG.runSuites(TestNG.java:1049)
178 | 	at org.testng.TestNG.run(TestNG.java:1017)
179 | 	at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114)
180 | 	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
181 | 	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
182 | 
0null

186 | 187 | -------------------------------------------------------------------------------- /src/gestures/AndroidGesture.java: -------------------------------------------------------------------------------- 1 | package gestures; 2 | 3 | import org.openqa.selenium.Dimension; 4 | import org.openqa.selenium.JavascriptExecutor; 5 | import org.openqa.selenium.Point; 6 | import org.openqa.selenium.WebElement; 7 | import org.testng.Assert; 8 | 9 | //import io.appium.java_client.MobileDriver; 10 | import io.appium.java_client.MultiTouchAction; 11 | import io.appium.java_client.TouchAction; 12 | import io.appium.java_client.android.AndroidDriver; 13 | import io.appium.java_client.touch.offset.PointOption; 14 | 15 | public class AndroidGesture { 16 | 17 | // Method to perform Tap gesture on given element 18 | @SuppressWarnings("rawtypes") 19 | public static void tap(AndroidDriver driver, Point frameLoc, WebElement element) { 20 | // Get element location and size 21 | Point elementLoc = element.getLocation(); 22 | Dimension elementSize = element.getSize(); 23 | 24 | // Get element center 25 | Point center = getPosition(driver, elementLoc, elementSize, frameLoc, "CENTER"); 26 | 27 | driver.context("NATIVE_APP"); 28 | 29 | // Perform tap gesture 30 | TouchAction action = new TouchAction(driver); 31 | action.tap(PointOption.point(center)).perform(); 32 | 33 | driver.context("CHROMIUM"); 34 | 35 | } 36 | 37 | // Method to perform Double Tap gesture on given element 38 | @SuppressWarnings("rawtypes") 39 | public static void doubleTap(AndroidDriver driver, Point frameLoc, WebElement element) { 40 | // Get element location and size 41 | Point elementLoc = element.getLocation(); 42 | Dimension elementSize = element.getSize(); 43 | 44 | // Get element center 45 | Point center = getPosition(driver, elementLoc, elementSize, frameLoc, "CENTER"); 46 | 47 | driver.context("NATIVE_APP"); 48 | 49 | // Perform tap gesture 50 | TouchAction action = new TouchAction(driver); 51 | action.tap(PointOption.point(center)).waitAction().tap(PointOption.point(center)).perform(); 52 | 53 | driver.context("CHROMIUM"); 54 | } 55 | 56 | // Method to perform Swipe gesture on given element 57 | @SuppressWarnings("rawtypes") 58 | public static void swipe(AndroidDriver driver, Point frameLoc, WebElement element, String direction) { 59 | // Get element location and size 60 | Point elementLoc = element.getLocation(); 61 | Dimension elementSize = element.getSize(); 62 | 63 | // Get element center as start location 64 | Point start = getPosition(driver, elementLoc, elementSize, frameLoc, "CENTER"); 65 | 66 | Point end = null; 67 | TouchAction action = new TouchAction(driver); 68 | 69 | // Based on direction, get left or right as end location 70 | switch (direction) { 71 | case "LEFT": 72 | end = getPosition(driver, elementLoc, elementSize, frameLoc, "LEFT"); 73 | break; 74 | case "RIGHT": 75 | end = getPosition(driver, elementLoc, elementSize, frameLoc, "RIGHT"); 76 | break; 77 | default: 78 | Assert.fail("Inavlid Direction: Please mention either LEFT or RIGHT"); 79 | } 80 | 81 | // perform swipe gesture 82 | driver.context("NATIVE_APP"); 83 | action.press(PointOption.point(start)).moveTo(PointOption.point(end)).release().perform(); 84 | driver.context("CHROMIUM"); 85 | } 86 | 87 | // Method to perform Swipe gesture on screen 88 | @SuppressWarnings("rawtypes") 89 | public static void swipe(AndroidDriver driver, String direction) { 90 | // Switch to default content 91 | driver.switchTo().defaultContent(); 92 | 93 | // Get DPR 94 | JavascriptExecutor js = (JavascriptExecutor) driver; 95 | long dpr = (long) js.executeScript("return (window.devicePixelRatio)"); 96 | 97 | // Get screen inner size 98 | long screenInnerWidth = (long) js.executeScript("return (window.innerWidth)"); 99 | long screenInnerHeight = (long) js.executeScript("return (window.innerHeight)"); 100 | 101 | // Calculate left and right mid of screen 102 | int y = (int) ((screenInnerHeight / 2) * dpr); 103 | int rightX = (int) ((screenInnerWidth - 20) * dpr); 104 | int leftX = (int) (20 * dpr); 105 | 106 | driver.context("NATIVE_APP"); 107 | 108 | TouchAction action = new TouchAction(driver); 109 | 110 | switch (direction) { 111 | case "LEFT": 112 | action.press(PointOption.point(rightX, y)).moveTo(PointOption.point(leftX, y)).release().perform(); 113 | break; 114 | case "RIGHT": 115 | action.press(PointOption.point(leftX, y)).moveTo(PointOption.point(rightX, y)).release().perform(); 116 | break; 117 | default: 118 | Assert.fail("Inavlid Direction: Please mention either LEFT or RIGHT"); 119 | } 120 | driver.context("CHROMIUM"); 121 | } 122 | 123 | // Method to perform Zoom Out gesture on given element 124 | @SuppressWarnings("rawtypes") 125 | public static void zoomOut(AndroidDriver driver, WebElement element, Point frameLoc) { 126 | // Get element location and size 127 | Point elementLoc = element.getLocation(); 128 | Dimension elementSize = element.getSize(); 129 | 130 | // Get center, left and right location 131 | Point center = getPosition(driver, elementLoc, elementSize, frameLoc, "CENTER"); 132 | Point left = getPosition(driver, elementLoc, elementSize, frameLoc, "LEFT"); 133 | Point right = getPosition(driver, elementLoc, elementSize, frameLoc, "RIGHT"); 134 | 135 | driver.context("NATIVE_APP"); 136 | 137 | // Create two TouchActions to swipe to left and right direction from center 138 | TouchAction action1 = new TouchAction(driver); 139 | TouchAction action2 = new TouchAction(driver); 140 | MultiTouchAction multiTouchAction = new MultiTouchAction(driver); 141 | 142 | action1.press(PointOption.point(center.getX() + 5, center.getY())).moveTo(PointOption.point(right)).release(); 143 | action2.press(PointOption.point(center.getX() - 5, center.getY())).moveTo(PointOption.point(left)).release(); 144 | 145 | // Perform zoom out gesture by performing simultaneous swipe to left and right 146 | // from center 147 | multiTouchAction.add(action1).add(action2).perform(); 148 | 149 | driver.context("CHROMIUM"); 150 | 151 | } 152 | 153 | // Method to perform Zoom In gesture on given element 154 | @SuppressWarnings("rawtypes") 155 | public static void zoomIn(AndroidDriver driver, WebElement element, Point frameLoc) { 156 | // Get element location and size 157 | Point elementLoc = element.getLocation(); 158 | Dimension elementSize = element.getSize(); 159 | 160 | // Get center, left and right location 161 | Point center = getPosition(driver, elementLoc, elementSize, frameLoc, "CENTER"); 162 | Point left = getPosition(driver, elementLoc, elementSize, frameLoc, "LEFT"); 163 | Point right = getPosition(driver, elementLoc, elementSize, frameLoc, "RIGHT"); 164 | 165 | driver.context("NATIVE_APP"); 166 | 167 | // Create two TouchActions to swipe from left and right direction to center 168 | TouchAction action1 = new TouchAction(driver); 169 | TouchAction action2 = new TouchAction(driver); 170 | MultiTouchAction multiTouchAction = new MultiTouchAction(driver); 171 | 172 | action1.press(PointOption.point(right)).moveTo(PointOption.point(center.getX() + 5, center.getY())).release(); 173 | action2.press(PointOption.point(left)).moveTo(PointOption.point(center.getX() - 5, center.getY())).release(); 174 | 175 | // Perform zoom in gesture by performing simultaneous swipe from left and right 176 | // to center 177 | multiTouchAction.add(action1).add(action2).perform(); 178 | 179 | driver.context("CHROMIUM"); 180 | 181 | } 182 | 183 | // Method to calculate Offset for convert CSS location to Physical location 184 | @SuppressWarnings("rawtypes") 185 | private static Point getOffset(AndroidDriver driver, Point frameLoc) { 186 | 187 | driver.switchTo().defaultContent(); 188 | 189 | // Get screen height and screen inner height 190 | JavascriptExecutor js = (JavascriptExecutor) driver; 191 | long screenHeight = (long) js.executeScript("return (window.screen.height)"); 192 | long screenInnerHeight = (long) js.executeScript("return (window.innerHeight)"); 193 | 194 | // Calculate offset 195 | int offsetX = frameLoc.getX(); 196 | int offsetY = (int) (screenHeight - screenInnerHeight + frameLoc.getY()); 197 | 198 | // return offset 199 | return new Point(offsetX, offsetY); 200 | } 201 | 202 | // Method to calculate coordinates of required position 203 | @SuppressWarnings("rawtypes") 204 | private static Point getPosition(AndroidDriver driver, Point elementLoc, Dimension elementSize, Point frameLoc, 205 | String position) { 206 | driver.switchTo().defaultContent(); 207 | 208 | // Calculate height of navigation bar of device 209 | int winH = driver.manage().window().getSize().getHeight(); 210 | int navH = (int) 7.5 * winH / 100; 211 | 212 | // TODO: To know if navigation bar is hidden or not. If hidden navH should be 0 213 | // and not 7.5% of device height 214 | 215 | // Get DPR 216 | JavascriptExecutor js = (JavascriptExecutor) driver; 217 | long dpr = (long) js.executeScript("return (window.devicePixelRatio)"); 218 | 219 | // Get screen inner size 220 | long screenInnerWidth = (long) js.executeScript("return (window.innerWidth)"); 221 | long screenInnerHeight = (long) js.executeScript("return (window.innerHeight)"); 222 | 223 | // Get offset 224 | Point offset = getOffset(driver, frameLoc); 225 | 226 | // Calculate physical location of element 227 | int physicalX = (int) ((elementLoc.getX() + offset.getX()) * dpr); 228 | int physicalY = (int) ((elementLoc.getY() + offset.getY()) * dpr - navH); 229 | 230 | // Calculate x coordinate of required position 231 | int x = 0; 232 | switch (position) { 233 | case "CENTER": 234 | x = (int) (physicalX + dpr * elementSize.getWidth() / 2); 235 | if (Math.abs(x) > screenInnerWidth) 236 | x = (int) (dpr * screenInnerWidth / 2); 237 | break; 238 | 239 | case "LEFT": 240 | x = (int) (physicalX + dpr * 10); 241 | if (Math.abs(x) > screenInnerWidth) 242 | x = (int) (dpr * 20); 243 | break; 244 | 245 | case "RIGHT": 246 | x = (int) (physicalX + dpr * (elementSize.getWidth() - 10)); 247 | if (Math.abs(x) > screenInnerWidth) 248 | x = (int) (dpr * (screenInnerWidth - 20)); 249 | break; 250 | default: 251 | Assert.fail("Invalid position: Please mention LEFT, RIGHT or CENTER"); 252 | 253 | } 254 | 255 | // Calculate y coordinate of required position 256 | int y = (int) (physicalY + dpr * elementSize.getHeight() / 2); 257 | if (Math.abs(y) > screenInnerHeight) 258 | y = (int) (dpr * screenInnerHeight / 2); 259 | 260 | // Return required position 261 | return new Point(x, y); 262 | } 263 | } 264 | -------------------------------------------------------------------------------- /test-output/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | TestNG reports 7 | 8 | 9 | 10 | 11 | 12 | 18 | 21 | 22 | 23 | 24 |

25 | Test results 26 |
27 | 1 suite, 1 failed test 28 |
29 | 145 |
146 |
147 |
148 |
149 |
150 | 151 | testScripts.TestScreenshot 152 |
153 |
154 |
155 |
156 | 157 | 158 | testFail 159 |
java.lang.AssertionError: null 160 | at testScripts.TestScreenshot.testFail(TestScreenshot.java:37) 161 | ... Removed 27 stack frames 162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 | 170 | testScripts.TestScreenshot 171 |
172 |
173 |
174 |
175 | 176 | 177 | testSkip 178 |
java.lang.Throwable: Method TestScreenshot.testSkip()[pri:0, instance:testScripts.TestScreenshot@306cf3ea] depends on not successfully finished methods 179 | ... Removed 18 stack frames 180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 | 188 | testScripts.TestScreenshot 189 |
190 |
191 |
192 |
193 | 194 | 195 | testPass 196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 | /Users/sara/eclipse-workspace/selenium-utility-master/src/resources/testScreenshot.xml 204 |
205 |
206 |
207 | <?xml version="1.0" encoding="UTF-8"?>
208 | <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
209 | <suite name="TestNGSuite" guice-stage="DEVELOPMENT">
210 |   <parameter name="webURL" value="https://www.google.com/"/>
211 |   <parameter name="webBrowser" value="chrome"/>
212 |   <listeners>
213 |     <listener class-name="utility.TestListener"/>
214 |   </listeners>
215 |   <test thread-count="5" name="Test">
216 |     <classes>
217 |       <class name="testScripts.TestScreenshot"/>
218 |     </classes>
219 |   </test> <!-- Test -->
220 | </suite> <!-- TestNGSuite -->
221 |             
222 |
223 |
224 |
225 |
226 | Tests for TestNGSuite 227 |
228 |
229 |
    230 |
  • 231 | Test (1 class) 232 |
  • 233 |
234 |
235 |
236 |
237 |
238 | Groups for TestNGSuite 239 |
240 |
241 |
242 |
243 |
244 |
245 | Times for TestNGSuite 246 |
247 |
248 |
249 | 274 | Total running time: 2 seconds 275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 | Reporter output for TestNGSuite 283 |
284 |
285 |
286 | testPass 287 |
288 | Result status: 1 289 | 290 |
291 |
292 |
293 | testFail 294 |
295 | Result status: 2 296 | 297 |
298 |
299 |
300 | testSkip 301 |
302 | Result status: 3 303 | 304 |
305 |
306 |
307 |
308 |
309 |
310 | 0 ignored methods 311 |
312 |
313 |
314 |
315 |
316 |
317 | Methods in chronological order 318 |
319 |
320 |
321 |
testScripts.TestScreenshot
322 |
323 | setUp(chrome, https://www.google.com/) 324 | 0 ms 325 |
326 |
327 | testPass 328 | 10020 ms 329 |
330 |
331 | 332 | 333 | testFail 334 | 12506 ms 335 |
336 |
337 | tearDown 338 | 14126 ms 339 |
340 |
341 |
342 |
343 |
344 | 345 | 346 | --------------------------------------------------------------------------------