├── 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
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/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 | Class name
4 | Method name
5 | Groups
6 |
7 | testScripts.Test1
8 |
9 |
10 | @Test
11 |
12 |
13 |
14 | test
15 |
16 |
17 | @BeforeClass
18 |
19 |
20 | @BeforeMethod
21 |
22 |
23 | @AfterMethod
24 |
25 |
26 | @AfterClass
27 |
28 |
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 | Suite Passed Failed Skipped testng.xml
7 | Total 1 1 1
8 | TestNGSuite
9 | 1 1 1 Link
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 | Time Delta (ms) Suite configuration Test configuration Class configuration Groups configuration Method configuration Test method Thread Instances
4 | 19/01/07 12:32:04 0 test
5 | main@1698097425
6 |
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 | Time Delta (ms) Suite configuration Test configuration Class configuration Groups configuration Method configuration Test method Thread Instances
4 | 19/01/07 12:32:04 0 test
5 | main@1698097425
6 |
7 |
--------------------------------------------------------------------------------
/test-output/old/TestNGSuite/classes.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Class name
4 | Method name
5 | Groups
6 |
7 | testScripts.TestScreenshot
8 |
9 |
10 | @Test
11 |
12 |
13 |
14 | testPass
15 |
16 |
17 |
18 | testSkip
19 |
20 |
21 |
22 | testFail
23 |
24 |
25 | @BeforeClass
26 |
27 |
28 | @BeforeMethod
29 |
30 |
31 | @AfterMethod
32 |
33 |
34 | @AfterClass
35 |
36 |
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 Result status: 1
2 |
3 | Result status: 2
4 |
5 | Result status: 3
6 |
7 |
--------------------------------------------------------------------------------
/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 forTestNGSuite
9 |
23 |
30 |
--------------------------------------------------------------------------------
/test-output/old/Default suite/toc.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Results for Default suite
4 |
5 |
6 |
7 |
8 | Results forDefault suite
9 |
23 |
24 |
25 | Default test (1/0/0)
26 | Results
27 |
28 |
29 |
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 | Time Delta (ms) Suite configuration Test configuration Class configuration Groups configuration Method configuration Test method Thread Instances
4 | 19/03/03 23:29:04 0 >>setUp
5 | main@1309238149
6 | 19/03/03 23:29:14 10012 testPass
7 | main@1309238149
8 | 19/03/03 23:29:17 12498 testFail
9 | main@1309238149
10 | 19/03/03 23:29:18 14118 <<tearDown
11 | main@1309238149
12 |
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 | Time Delta (ms) Suite configuration Test configuration Class configuration Groups configuration Method configuration Test method Thread Instances
4 | 19/03/03 23:29:04 0 >>setUp
5 | main@1309238149
6 | 19/03/03 23:29:18 14118 <<tearDown
7 | main@1309238149
8 | 19/03/03 23:29:17 12498 testFail
9 | main@1309238149
10 | 19/03/03 23:29:14 10012 testPass
11 | main@1309238149
12 |
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 | Tests passed/Failed/Skipped: 1/0/0
59 |
60 | Started on: Mon Jan 07 12:32:04 IST 2019
61 |
62 | Total time: 0 seconds (36 ms)
63 |
64 | Included groups:
65 |
66 | Excluded groups:
67 |
68 |
69 | (Hover the method name to see the test class name)
70 |
71 | PASSED TESTS
72 | Test method
73 | Exception
74 | Time (seconds)
75 | Instance
76 |
77 |
78 | test Test class: testScripts.Test1
79 |
80 | 0
81 | testScripts.Test1@14bf9759
82 |
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 | Test # Passed # Skipped # Failed Time (ms) Included Groups Excluded Groups
11 | TestNGSuite
12 | Test 1 1 1 4,085
13 |
14 | Class Method Start Time (ms) TestNGSuite Test — failed testScripts.TestScreenshot testFail 1551635957272 587 Test — skipped testScripts.TestScreenshot testSkip 1551635958362 0 Test — passed testScripts.TestScreenshot testPass 1551635954786 2011
15 |
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 | Tests passed/Failed/Skipped: 1/1/1
59 |
60 | Started on: Tue Jan 08 14:43:14 IST 2019
61 |
62 | Total time: 8 seconds (8084 ms)
63 |
64 | Included groups:
65 |
66 | Excluded groups:
67 |
68 |
69 | (Hover the method name to see the test class name)
70 |
71 | FAILED TESTS
72 | Test method
73 | Exception
74 | Time (seconds)
75 | Instance
76 |
77 |
78 | testFail Test class: testScripts.TestNG
79 | Show output
80 |
81 | Show all outputs
82 |
83 | Result status: 2
84 |
85 |
86 |
87 | 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 |
120 | 0
121 | testScripts.TestNG@5f2108b5
122 |
123 |
124 | PASSED TESTS
125 | Test method
126 | Exception
127 | Time (seconds)
128 | Instance
129 |
130 |
131 | testPass Test class: testScripts.TestNG
132 | Show output
133 |
134 | Show all outputs
135 |
136 | Result status: 1
137 |
138 |
139 |
140 |
141 | 7
142 | testScripts.TestNG@5f2108b5
143 |
144 |
145 | SKIPPED TESTS
146 | Test method
147 | Exception
148 | Time (seconds)
149 | Instance
150 |
151 |
152 | testSkip Test class: testScripts.TestNG
153 | Show output
154 |
155 | Show all outputs
156 |
157 | Result status: 3
158 |
159 |
160 |
161 | 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 |
183 | 0
184 | null
185 |
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 | Tests passed/Failed/Skipped: 1/1/1
59 |
60 | Started on: Sun Mar 03 23:29:14 IST 2019
61 |
62 | Total time: 4 seconds (4085 ms)
63 |
64 | Included groups:
65 |
66 | Excluded groups:
67 |
68 |
69 | (Hover the method name to see the test class name)
70 |
71 | FAILED TESTS
72 | Test method
73 | Exception
74 | Time (seconds)
75 | Instance
76 |
77 |
78 | testFail Test class: testScripts.TestScreenshot
79 | Show output
80 |
81 | Show all outputs
82 |
83 | Result status: 2
84 |
85 |
86 |
87 | 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 |
120 | 0
121 | testScripts.TestScreenshot@306cf3ea
122 |
123 |
124 | PASSED TESTS
125 | Test method
126 | Exception
127 | Time (seconds)
128 | Instance
129 |
130 |
131 | testPass Test class: testScripts.TestScreenshot
132 | Show output
133 |
134 | Show all outputs
135 |
136 | Result status: 1
137 |
138 |
139 |
140 |
141 | 2
142 | testScripts.TestScreenshot@306cf3ea
143 |
144 |
145 | SKIPPED TESTS
146 | Test method
147 | Exception
148 | Time (seconds)
149 | Instance
150 |
151 |
152 | testSkip Test class: testScripts.TestScreenshot
153 | Show output
154 |
155 | Show all outputs
156 |
157 | Result status: 3
158 |
159 |
160 |
161 | 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 |
183 | 0
184 | null
185 |
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 |
30 |
37 |
38 |
39 |
44 |
45 |
46 | Info
47 |
48 |
87 |
88 |
89 | Results
90 |
91 |
92 |
93 |
94 | 3 methods, 1 failed, 1 skipped, 1 passed
95 |
96 |
97 | Failed methods
98 |
99 | (hide)
100 | (show)
101 |
102 |
103 |
104 |
105 | testFail
106 |
107 |
108 |
109 |
110 |
111 | Skipped methods
112 |
113 | (hide)
114 | (show)
115 |
116 |
117 |
118 |
119 | testSkip
120 |
121 |
122 |
123 |
124 |
125 | Passed methods
126 |
127 | (hide)
128 | (show)
129 |
130 |
131 |
132 |
133 | testPass
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
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 |
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 |
227 |
228 |
229 |
230 |
231 | Test (1 class)
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
274 |
Total running time: 2 seconds
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
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 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
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 |
--------------------------------------------------------------------------------