├── .gitignore ├── LICENSE ├── README.md ├── data └── config.properties ├── libs └── chromedriver.exe ├── pom.xml ├── src └── com │ └── nat │ └── test │ ├── GitTest.java │ ├── RepositoryTest.java │ ├── TestData.java │ ├── pages │ ├── CreateRepositoryPage.java │ ├── HomePage.java │ ├── IssuePage.java │ ├── IssuesSectionPage.java │ ├── LoginPage.java │ ├── NotificationsPage.java │ ├── OptionsPage.java │ ├── Page.java │ ├── RepositoryAbstractPage.java │ ├── RepositoryPage.java │ ├── SearchPage.java │ └── StartPage.java │ └── utils │ ├── ConfigReader.java │ ├── PageNavigator.java │ └── XLSWorker.java └── xls └── TestCases.xlsx /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | test-output/ 3 | target/ 4 | .settings/ 5 | .classpath 6 | .project 7 | *.iml 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Natalya11444 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GitHub-Test-Framework 2 | This is an example of test automation framework usind Selenium WebDriver and TestNG. Takes data for the test 3 | from excel file and saves test result from each step and certain data. Name, password, browser and using assertion or verifying are taken from the config.properties file. 4 | -------------------------------------------------------------------------------- /data/config.properties: -------------------------------------------------------------------------------- 1 | # Valid login 2 | LOGIN=testgit5 3 | # Valid password 4 | PASSWORD=testpass1 5 | # Enter prefer browser (now available "FIREFOX", "CHROME") 6 | BROWSER=FIREFOX 7 | # Enter path to Firefox profile 8 | FIREFOX_PATH= 9 | # Enter "true" if you would like to use TestNG assertions, "false" if wouldn't 10 | USE_ASSERT=true -------------------------------------------------------------------------------- /libs/chromedriver.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natlg/Selenium-TestNG-Test-Framework/3783876644e781bb60db1512e1774b8a2810e00f/libs/chromedriver.exe -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.nat.test 5 | githubtest 6 | 0.0.1-SNAPSHOT 7 | 8 | src 9 | 10 | 11 | maven-compiler-plugin 12 | 3.1 13 | 14 | 1.7 15 | 1.7 16 | 17 | 18 | 19 | 20 | 21 | 22 | org.testng 23 | testng 24 | 6.8.21 25 | 26 | 27 | 28 | org.seleniumhq.selenium 29 | selenium-support 30 | 2.45.0 31 | 32 | 33 | org.seleniumhq.selenium 34 | selenium-chrome-driver 35 | 2.45.0 36 | 37 | 38 | org.seleniumhq.selenium 39 | selenium-firefox-driver 40 | 2.45.0 41 | 42 | 43 | 44 | org.apache.poi 45 | poi 46 | 3.11 47 | 48 | 49 | org.apache.poi 50 | poi-ooxml 51 | 3.11 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/com/nat/test/GitTest.java: -------------------------------------------------------------------------------- 1 | package com.nat.test; 2 | 3 | import java.util.List; 4 | 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.support.PageFactory; 8 | import org.testng.annotations.AfterClass; 9 | import org.testng.annotations.AfterMethod; 10 | import org.testng.annotations.BeforeClass; 11 | import org.testng.annotations.BeforeMethod; 12 | import org.testng.annotations.DataProvider; 13 | import org.testng.annotations.Test; 14 | 15 | import com.nat.test.pages.HomePage; 16 | import com.nat.test.pages.LoginPage; 17 | import com.nat.test.pages.NotificationsPage; 18 | import com.nat.test.pages.SearchPage; 19 | import com.nat.test.pages.StartPage; 20 | import com.nat.test.utils.PageNavigator; 21 | 22 | public class GitTest { 23 | private WebDriver driver; 24 | private SearchPage searchPage; 25 | private HomePage homePage; 26 | private StartPage startPage; 27 | private boolean passedWithCertainData; 28 | private boolean passedSearchTest = true; 29 | private LoginPage loginPage; 30 | private NotificationsPage notificationsPage; 31 | private PageNavigator pageNavigator = new PageNavigator(); 32 | 33 | @BeforeClass 34 | public void beforeClass() { 35 | driver = TestData.getDriver(); 36 | } 37 | 38 | @BeforeMethod 39 | public void beforeTest() { 40 | driver.get(TestData.BASE_URL); 41 | } 42 | 43 | @AfterClass 44 | public void afterClass() { 45 | driver.quit(); 46 | } 47 | 48 | /** 49 | * Tests correct login. 50 | *

51 | * 1. Go to the login page
52 | * 2. Check login form is presented
53 | * 3. Try to login with incorrect data and check that error message appears 54 | *
55 | * 4. Login with correct data, check that login was successful
56 | * 5. Logout, check that logout was successful 57 | */ 58 | 59 | @Test(enabled = true) 60 | public void testLogin() { 61 | 62 | // 1 step 63 | loginPage = pageNavigator.getLoginPage(driver); 64 | TestData.saveTestResult(TestData.TEST_LOGIN, TestData.STEP_1, 65 | null != loginPage); 66 | 67 | // 2 step 68 | TestData.saveTestResult(TestData.TEST_LOGIN, TestData.STEP_2, 69 | loginPage.isLoginFormPresents()); 70 | 71 | // 3 step 72 | loginPage.loginAsExpectingError("qqq", "qqq"); 73 | TestData.saveTestResult(TestData.TEST_LOGIN, TestData.STEP_3, 74 | loginPage.isErrorMessagePresents()); 75 | 76 | // 4 step 77 | HomePage homePage = loginPage 78 | .loginAs(TestData.LOGIN, TestData.PASSWORD); 79 | TestData.saveTestResult(TestData.TEST_LOGIN, TestData.STEP_4, 80 | homePage.isLoginSuccessed()); 81 | 82 | // 5 step 83 | startPage = pageNavigator.logout(driver, homePage); 84 | TestData.saveTestResult(TestData.TEST_LOGIN, TestData.STEP_5, 85 | startPage.isLoginPresents()); 86 | } 87 | 88 | /** 89 | * Tests notification. 90 | *

91 | * 1. Log in, check that notifications icon presents on the home page
92 | * 2. Click the notifications icon, check that all sections present
93 | */ 94 | @Test(enabled = true) 95 | public void testNotifications() { 96 | 97 | // 1 step 98 | homePage = pageNavigator.login(driver); 99 | TestData.saveTestResult(TestData.TEST_NOTIFICATIONS, TestData.STEP_1, 100 | homePage.isNotificationsIconPresents()); 101 | 102 | // 2 step 103 | notificationsPage = homePage.seeNotifications(); 104 | TestData.saveTestResult(TestData.TEST_NOTIFICATIONS, TestData.STEP_2, 105 | notificationsPage.isNoticicationsPresent()); 106 | notificationsPage.logout(); 107 | } 108 | 109 | /** 110 | * Tests correct search. 111 | *

112 | * 1. Go to the login page and check that it contains search field
113 | * 2. Fill the search field with the query and check that search result 114 | * appears (if no search result, then message appears)
115 | */ 116 | @Test(dataProvider = "searchQueriesProvider", enabled = true, groups = { "search" }) 117 | public void testSearch(String searchQuery, String hasResultStr) { 118 | // 1 step 119 | startPage = PageFactory.initElements(driver, StartPage.class); 120 | passedWithCertainData = startPage.isSearchPresents(); 121 | TestData.saveTestResult(TestData.TEST_SEARCH, TestData.STEP_1, 122 | passedWithCertainData); 123 | 124 | // 2 step 125 | searchPage = pageNavigator.search(driver, searchQuery, startPage); 126 | passedWithCertainData = searchPage.isResultMatch( 127 | Boolean.parseBoolean(hasResultStr), searchQuery); 128 | if (!passedWithCertainData) { 129 | passedSearchTest = false; 130 | } 131 | TestData.saveTestResultWithData(TestData.TEST_SEARCH, 132 | passedWithCertainData, searchQuery); 133 | } 134 | 135 | @AfterMethod(groups = { "search" }) 136 | public void afterSearch() { 137 | // Save result as passed only if test passed with all data from 138 | // DataProvider 139 | driver.get(TestData.BASE_URL); 140 | TestData.saveTestResult(TestData.TEST_SEARCH, TestData.STEP_2, 141 | passedSearchTest); 142 | } 143 | 144 | @DataProvider(name = "searchQueriesProvider") 145 | public Object[][] createQuery() { 146 | return TestData.getSearchData("testSearch"); 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /src/com/nat/test/RepositoryTest.java: -------------------------------------------------------------------------------- 1 | package com.nat.test; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | import org.testng.annotations.AfterClass; 5 | import org.testng.annotations.BeforeClass; 6 | import org.testng.annotations.BeforeMethod; 7 | import org.testng.annotations.Test; 8 | 9 | import com.nat.test.pages.CreateRepositoryPage; 10 | import com.nat.test.pages.HomePage; 11 | import com.nat.test.pages.IssuePage; 12 | import com.nat.test.pages.IssuesSectionPage; 13 | import com.nat.test.pages.OptionsPage; 14 | import com.nat.test.pages.RepositoryPage; 15 | import com.nat.test.pages.StartPage; 16 | import com.nat.test.utils.PageNavigator; 17 | 18 | public class RepositoryTest { 19 | 20 | private WebDriver driver; 21 | private HomePage homePage; 22 | private CreateRepositoryPage createRepositoryPage; 23 | private String currentRepName; 24 | private String repDescription = "NewDescription"; 25 | private boolean addReadme = true; 26 | private String gitignore = "Java"; 27 | private String license = "MIT"; 28 | private RepositoryPage repositoryPage; 29 | private PageNavigator pageNavigator = new PageNavigator(); 30 | private OptionsPage optionsPage; 31 | private IssuesSectionPage issuesSectionPage; 32 | private StartPage startPage; 33 | 34 | @BeforeClass 35 | public void beforeClass() { 36 | driver = TestData.getDriver(); 37 | } 38 | 39 | @BeforeMethod 40 | public void beforeTest() { 41 | // homePage = pageNavigator.getHomePage(driver); 42 | } 43 | 44 | @AfterClass 45 | public void afterClass() { 46 | driver.quit(); 47 | } 48 | 49 | /** 50 | * Tests correct repository creating. 51 | *

52 | * 1. Log in, check that button to create repository presents and click it
53 | * 2. Check that form for creating repository is presented and options to 54 | * choose owner, gitignore and license work correct
55 | * 3. Fill form with correct data and submit
56 | * 4. Check that name of the just created repository is the same as from 57 | * creating and check that code, issues, pullRequests, wiki, pulse, graphs 58 | * and settings sections are presented
59 | * 5. Delete this repository 60 | */ 61 | @Test(enabled = true) 62 | public void testAddRepository() { 63 | // 1 step 64 | homePage = pageNavigator.login(driver); 65 | TestData.saveTestResult(TestData.TEST_ADD_REPOSITORY, TestData.STEP_1, 66 | homePage.isNewRepoButtonPresents()); 67 | createRepositoryPage = homePage.createNewRepository(); 68 | 69 | // 2 step 70 | TestData.saveTestResult(TestData.TEST_ADD_REPOSITORY, TestData.STEP_2, 71 | createRepositoryPage.isNewRepFormExists() 72 | && createRepositoryPage.isNewRepFormJSWorks()); 73 | 74 | // 3 step 75 | String repName = pageNavigator.getUniqueRepName(); 76 | repositoryPage = createRepositoryPage.createRepository(repName, 77 | repDescription, addReadme, gitignore, license); 78 | TestData.saveTestResult(TestData.TEST_ADD_REPOSITORY, TestData.STEP_3, 79 | null != repositoryPage); 80 | 81 | // 4 step 82 | TestData.saveTestResult(TestData.TEST_ADD_REPOSITORY, TestData.STEP_4, 83 | repositoryPage.getRepositoryName().equals(repName) 84 | && repositoryPage.areRepSectionsPresent()); 85 | 86 | // 5 step 87 | startPage = pageNavigator.deleteRepositiryAndLogout(driver, repName, 88 | repositoryPage); 89 | TestData.saveTestResult(TestData.TEST_ADD_REPOSITORY, TestData.STEP_5, 90 | null != startPage); 91 | } 92 | 93 | /** 94 | * Tests correct repository deleting 95 | *

96 | * 1. Create new repository, go to settings
97 | * 2. Check that option to delete exists
98 | * 3. Delete repository, check that message about successful deleting 99 | * appeared and check that name of deleted repository is not presented in 100 | * the list of existing repositories 101 | */ 102 | @Test(enabled = true) 103 | public void testDeleteRepository() { 104 | // 1 step 105 | repositoryPage = pageNavigator.getNewRepositoryPage(driver, 106 | repDescription, addReadme, gitignore, license); 107 | currentRepName = TestData.getData().getRepositoryName(); 108 | OptionsPage optionsPage = repositoryPage.goToSettings(); 109 | TestData.saveTestResult(TestData.TEST_DELETE_REPOSITORY, 110 | TestData.STEP_1, null != optionsPage); 111 | 112 | // 2 step 113 | TestData.saveTestResult(TestData.TEST_DELETE_REPOSITORY, 114 | TestData.STEP_2, optionsPage.isDeletePresents()); 115 | 116 | // 3 step 117 | homePage = optionsPage.deleteRepository(currentRepName); 118 | TestData.saveTestResult(TestData.TEST_DELETE_REPOSITORY, 119 | TestData.STEP_3, 120 | homePage.isRepositoryJustDeleted(currentRepName)); 121 | homePage.logout(); 122 | } 123 | 124 | /** 125 | * Tests correct issue adding. 126 | *

127 | * 1. Log in, add new repository
128 | * 2. Click on Issues link, check that all sections and welcome message 129 | * present
130 | * 3. Click the link to create issue, check that Title, Comments fields and 131 | * Labels, Milestone, Assignee links present
132 | * 4. Fill all fields and confirm creating, check that issue submitted
133 | * 5. Navigate to Issues Section page and check that new issue appeared in 134 | * the list of issues
135 | * 6. Delete repository 136 | */ 137 | @Test(enabled = true) 138 | public void testAddIssue() { 139 | // 1 step 140 | repositoryPage = pageNavigator.getNewRepositoryPage(driver, 141 | repDescription, addReadme, gitignore, license); 142 | TestData.saveTestResult(TestData.TEST_ADD_ISSUE, TestData.STEP_1, 143 | null != repositoryPage); 144 | 145 | // 2 step 146 | issuesSectionPage = repositoryPage.goToIssues(); 147 | TestData.saveTestResult( 148 | TestData.TEST_ADD_ISSUE, 149 | TestData.STEP_2, 150 | issuesSectionPage.areAllElementsPresent() 151 | && issuesSectionPage.isWelcomeMessagePresent()); 152 | 153 | // 3 step 154 | IssuePage issuePage = issuesSectionPage.addNewIssue(); 155 | TestData.saveTestResult(TestData.TEST_ADD_ISSUE, TestData.STEP_3, 156 | issuePage.areNewIssueElementsPresent()); 157 | 158 | // 4 step 159 | String title = "New issue"; 160 | String comment = "Comment"; 161 | issuePage.addIssue(title, comment); 162 | TestData.saveTestResult(TestData.TEST_ADD_ISSUE, TestData.STEP_4, 163 | issuePage.IsIssueJustAdded()); 164 | 165 | // 5 step 166 | issuesSectionPage = issuePage.goToIssues(); 167 | TestData.saveTestResult(TestData.TEST_ADD_ISSUE, TestData.STEP_5, 168 | issuesSectionPage.isIssuePresent(title)); 169 | 170 | // 6 step 171 | homePage = pageNavigator.deleteRepository(driver, issuesSectionPage); 172 | TestData.saveTestResult(TestData.TEST_ADD_ISSUE, TestData.STEP_6, 173 | null != homePage); 174 | homePage.logout(); 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/com/nat/test/TestData.java: -------------------------------------------------------------------------------- 1 | package com.nat.test; 2 | 3 | import java.io.File; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | import org.openqa.selenium.WebDriver; 7 | import org.openqa.selenium.chrome.ChromeDriver; 8 | import org.openqa.selenium.firefox.FirefoxDriver; 9 | import org.openqa.selenium.firefox.FirefoxProfile; 10 | import org.testng.Assert; 11 | 12 | import com.nat.test.pages.StartPage; 13 | import com.nat.test.utils.ConfigReader; 14 | import com.nat.test.utils.XLSWorker; 15 | 16 | /** 17 | * Class provides data and settings for tests and saves test results 18 | */ 19 | public class TestData { 20 | private static final ConfigReader configReader = new ConfigReader(); 21 | public static String BROWSER = configReader.getBrowser(); 22 | public static String FIREFOX_PATH = configReader.getFirefoxPath(); 23 | public static final String BASE_URL = "https://github.com/"; 24 | private static WebDriver driver; 25 | public static final String LOGIN = configReader.getLogin(); 26 | public static final String PASSWORD = configReader.getPassword(); 27 | public static final boolean USE_ASSERT = configReader.isUseAssert(); 28 | public static final int WAIT_TIME = 10; 29 | public static final int TEST_LOGIN = 1; 30 | public static final int TEST_SEARCH = 2; 31 | public static final int TEST_NOTIFICATIONS = 3; 32 | public static final int TEST_ADD_REPOSITORY = 4; 33 | public static final int TEST_DELETE_REPOSITORY = 5; 34 | public static final int TEST_ADD_ISSUE = 6; 35 | public static final int STEP_1 = 1; 36 | public static final int STEP_2 = 2; 37 | public static final int STEP_3 = 3; 38 | public static final int STEP_4 = 4; 39 | public static final int STEP_5 = 5; 40 | public static final int STEP_6 = 6; 41 | public static final int STEP_7 = 7; 42 | public static final String SHEET_NAME_TEST_CASE = "TestCases"; 43 | public static final String SHEET_NAME_TEST_DATA = "TestData"; 44 | private final static String xlsPath = "xls\\TestCases.xlsx"; 45 | private static XLSWorker xlsWorker = new XLSWorker(xlsPath); 46 | private static final int START_ROW_NUM_LOGIN_TEST = 1; 47 | private static final int START_ROW_NUM_SEARCH_TEST = 6; 48 | private static final int START_ROW_NUM_NOTIF_TEST = 8; 49 | private static final int START_ROW_NUM_ADD_REP_TEST = 10; 50 | private static final int START_ROW_NUM_DELETE_REP_TEST = 15; 51 | private static final int START_ROW_NUM_ADD_ISSUE = 18; 52 | private String repositoryName; 53 | private static TestData data; 54 | 55 | private TestData() { 56 | } 57 | 58 | /** 59 | * Method to get instance of the class 60 | * 61 | * @return An instance of the {@link TestData} class 62 | */ 63 | public static TestData getData() { 64 | if (null == data) { 65 | data = new TestData(); 66 | } 67 | return data; 68 | } 69 | 70 | /** 71 | * Saves test results to the excel file (passed or fail) 72 | * 73 | * @param testCase 74 | * Test case 75 | * @param step 76 | * Step of the test case 77 | * @param passed 78 | * Test result 79 | */ 80 | public static void saveTestResult(int testCase, int step, boolean passed) { 81 | switch (testCase) { 82 | case TEST_LOGIN: 83 | xlsWorker.setCellData(TestData.SHEET_NAME_TEST_CASE, "Result", step 84 | + START_ROW_NUM_LOGIN_TEST, passed ? "Passed" : "Fail"); 85 | break; 86 | case TEST_SEARCH: 87 | xlsWorker.setCellData(TestData.SHEET_NAME_TEST_CASE, "Result", step 88 | + START_ROW_NUM_SEARCH_TEST, passed ? "Passed" : "Fail"); 89 | break; 90 | case TEST_NOTIFICATIONS: 91 | xlsWorker.setCellData(TestData.SHEET_NAME_TEST_CASE, "Result", step 92 | + START_ROW_NUM_NOTIF_TEST, passed ? "Passed" : "Fail"); 93 | break; 94 | case TEST_ADD_REPOSITORY: 95 | xlsWorker.setCellData(TestData.SHEET_NAME_TEST_CASE, "Result", step 96 | + START_ROW_NUM_ADD_REP_TEST, passed ? "Passed" : "Fail"); 97 | break; 98 | case TEST_DELETE_REPOSITORY: 99 | xlsWorker 100 | .setCellData(TestData.SHEET_NAME_TEST_CASE, "Result", step 101 | + START_ROW_NUM_DELETE_REP_TEST, passed ? "Passed" 102 | : "Fail"); 103 | break; 104 | case TEST_ADD_ISSUE: 105 | xlsWorker.setCellData(TestData.SHEET_NAME_TEST_CASE, "Result", step 106 | + START_ROW_NUM_ADD_ISSUE, passed ? "Passed" : "Fail"); 107 | break; 108 | 109 | default: 110 | System.out.println("No Test Case with number " + testCase 111 | + " is found "); 112 | break; 113 | } 114 | if (USE_ASSERT) { 115 | Assert.assertTrue(passed); 116 | } 117 | } 118 | 119 | /** 120 | * Saves test results from certain test data to the excel file (passed or 121 | * fail) 122 | * 123 | * @param testCase 124 | * Test case 125 | * @param passed 126 | * Test result 127 | * @param data 128 | * Test data 129 | */ 130 | public static void saveTestResultWithData(int testCase, boolean passed, 131 | String data) { 132 | switch (testCase) { 133 | case TEST_LOGIN: 134 | // uncomment, if this test will have data 135 | // xlsWorker.setCellData(TestData.SHEET_NAME_TEST_DATA, 136 | // "testLogin", 137 | // data, passed ? "Passed" : "Fail"); 138 | break; 139 | case TEST_SEARCH: 140 | xlsWorker.setCellData(TestData.SHEET_NAME_TEST_DATA, "testSearch", 141 | data, passed ? "Passed" : "Fail"); 142 | break; 143 | case TEST_NOTIFICATIONS: 144 | // uncomment, if this test will have data 145 | // xlsWorker.setCellData(TestData.SHEET_NAME_TEST_DATA, 146 | // "testNotifications", 147 | // data, passed ? "Passed" : "Fail"); 148 | break; 149 | case TEST_ADD_REPOSITORY: 150 | // uncomment, if this test will have data 151 | // xlsWorker.setCellData(TestData.SHEET_NAME_TEST_DATA, 152 | // "testAddRepository", 153 | // data, passed ? "Passed" : "Fail"); 154 | break; 155 | case TEST_DELETE_REPOSITORY: 156 | // uncomment, if this test will have data 157 | // xlsWorker.setCellData(TestData.SHEET_NAME_TEST_DATA, 158 | // "testDeleteRepository", 159 | // data, passed ? "Passed" : "Fail"); 160 | break; 161 | case TEST_ADD_ISSUE: 162 | // uncomment, if this test will have data 163 | // xlsWorker.setCellData(TestData.SHEET_NAME_TEST_DATA, 164 | // " testAddIssue", 165 | // data, passed ? "Passed" : "Fail"); 166 | break; 167 | default: 168 | System.out.println("No Test Case with number " + testCase 169 | + " is found in the file"); 170 | break; 171 | } 172 | } 173 | 174 | /** 175 | * Method to get the data for dataProvider from the file 176 | * 177 | ** @param testCase 178 | * Test case 179 | * 180 | * @return array of data 181 | */ 182 | public static Object[][] getSearchData(String testCase) { 183 | try { 184 | return xlsWorker.getDataForTest(testCase); 185 | } catch (Exception e) { 186 | e.printStackTrace(); 187 | System.out.println("Can't read the test data"); 188 | return null; 189 | } 190 | 191 | } 192 | 193 | /** 194 | * Method to get the driver. WebDriver type is determined in 195 | * config.properties. By the default returns an instance of 196 | * {@link FirefoxDriver} 197 | * 198 | * @return driver 199 | */ 200 | public static synchronized WebDriver getDriver() { 201 | if (null == driver) { 202 | switch (BROWSER) { 203 | case "FIREFOX": 204 | if (!FIREFOX_PATH.equals("")) { 205 | try { 206 | File pathToProfile = new File(FIREFOX_PATH); 207 | FirefoxProfile profile = new FirefoxProfile( 208 | pathToProfile); 209 | driver = new FirefoxDriver(profile); 210 | } catch (Exception e) { 211 | e.printStackTrace(); 212 | driver = new FirefoxDriver(); 213 | } 214 | } else { 215 | driver = new FirefoxDriver(); 216 | } 217 | break; 218 | case "CHROME": 219 | String chromepath = "libs\\chromedriver.exe"; 220 | System.setProperty("webdriver.chrome.driver", chromepath); 221 | driver = new ChromeDriver(); 222 | driver.manage().window().maximize(); 223 | break; 224 | 225 | default: 226 | driver = new FirefoxDriver(); 227 | break; 228 | } 229 | driver.manage().timeouts() 230 | .implicitlyWait(WAIT_TIME, TimeUnit.SECONDS); 231 | } 232 | return driver; 233 | } 234 | 235 | public String getRepositoryName() { 236 | return repositoryName; 237 | } 238 | 239 | public void setRepositoryName(String repositoryName) { 240 | this.repositoryName = repositoryName; 241 | } 242 | 243 | } 244 | -------------------------------------------------------------------------------- /src/com/nat/test/pages/CreateRepositoryPage.java: -------------------------------------------------------------------------------- 1 | package com.nat.test.pages; 2 | 3 | import java.util.List; 4 | 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.interactions.Actions; 8 | import org.openqa.selenium.support.FindBy; 9 | import org.openqa.selenium.support.PageFactory; 10 | 11 | import com.nat.test.TestData; 12 | import com.nat.test.utils.PageNavigator; 13 | 14 | /** 15 | * Class represents page with the form for creating new repository 16 | */ 17 | public class CreateRepositoryPage extends Page { 18 | 19 | @FindBy(name = "q") 20 | private WebElement search; 21 | 22 | @FindBy(id = "repository_name") 23 | private WebElement repNameElement; 24 | 25 | @FindBy(id = "repository_description") 26 | private WebElement repDescription; 27 | 28 | @FindBy(xpath = "//*[contains (text(), 'Create repository')]") 29 | private WebElement repSubmit; 30 | 31 | @FindBy(xpath = "//div[contains(@class, 'owner-container')]/span") 32 | private WebElement owner; 33 | 34 | @FindBy(xpath = "//input[@type='radio'][@id='repository_public_true']") 35 | private WebElement publicRep; 36 | 37 | @FindBy(xpath = "//input[@type='radio'][@id='repository_public_false']") 38 | private WebElement privateRep; 39 | 40 | @FindBy(id = "repository_auto_init") 41 | private WebElement autoInit; 42 | 43 | @FindBy(xpath = "//*[contains(text(), 'Add .gitignore')]") 44 | private WebElement addGitignore; 45 | 46 | @FindBy(id = "context-ignore-filter-field") 47 | private WebElement chooseGitignore; 48 | 49 | @FindBy(xpath = "//div[@class='select-menu-item js-navigation-item']/div") 50 | private List gitignoreList; 51 | 52 | @FindBy(xpath = "//*[contains(text(), 'Add a license')]") 53 | private WebElement addLicense; 54 | 55 | @FindBy(xpath = "//div[@class='select-menu-item js-navigation-item']/div") 56 | private List licenseList; 57 | 58 | @FindBy(id = "context-license-filter-field") 59 | private WebElement chooseLicense; 60 | 61 | @FindBy(xpath = "//button[contains(@class, 'sign-out-button')]") 62 | private WebElement logout; 63 | 64 | @FindBy(xpath = "//*[contains(text(), 'Choose another owner')]") 65 | private WebElement chooseOwner; 66 | 67 | private String repName; 68 | 69 | /** 70 | * Class constructor 71 | * 72 | * @param driver 73 | * The driver that will be used for navigation 74 | * @throws IllegalStateException 75 | * If it's not expected page 76 | */ 77 | public CreateRepositoryPage(WebDriver driver) { 78 | super(driver); 79 | } 80 | 81 | /** 82 | * Checks if the form for creating new repository presents on the page 83 | * 84 | * @return true if all form elements present on the page 85 | */ 86 | public boolean isNewRepFormExists() { 87 | return isElementPresents(repNameElement) 88 | && isElementPresents(repDescription) 89 | && isElementPresents(repSubmit) && isElementPresents(owner) 90 | && isElementPresents(publicRep) 91 | && isElementPresents(privateRep) && isElementPresents(autoInit) 92 | && isElementPresents(addGitignore) 93 | && isElementPresents(addLicense); 94 | } 95 | 96 | /** 97 | * Log out 98 | * 99 | * @return An instance of {@link StartPage} class 100 | */ 101 | public StartPage logout() { 102 | logout.click(); 103 | return PageFactory.initElements(driver, StartPage.class); 104 | } 105 | 106 | /** 107 | * Check if dropdowns to choose owner, gitignore and license appear if click 108 | * theirs elements 109 | * 110 | * @return True if dropdowns to choose owner, gitignore and license appear 111 | * if click it's elements 112 | */ 113 | public boolean isNewRepFormJSWorks() { 114 | boolean isChooseOwnerPresents; 115 | boolean isGitignorePresents; 116 | boolean isLicensePresents; 117 | PageNavigator.click(driver, owner); 118 | if (!isElementPresents(chooseOwner)) { 119 | owner.click(); 120 | isChooseOwnerPresents = isElementPresents(chooseOwner); 121 | } else { 122 | isChooseOwnerPresents = true; 123 | } 124 | 125 | PageNavigator.click(driver, addGitignore); 126 | if (!isElementPresents(chooseGitignore)) { 127 | addGitignore.click(); 128 | isGitignorePresents = isElementPresents(addGitignore); 129 | } else { 130 | isGitignorePresents = true; 131 | } 132 | 133 | PageNavigator.click(driver, addLicense); 134 | if (!isElementPresents(chooseLicense)) { 135 | addLicense.click(); 136 | isLicensePresents = isElementPresents(addLicense); 137 | } else { 138 | isLicensePresents = true; 139 | } 140 | return isChooseOwnerPresents && isGitignorePresents 141 | && isLicensePresents; 142 | } 143 | 144 | /** 145 | * Method to get the page with just created repository. 146 | * 147 | * @param repName 148 | * New repository name 149 | * @param repDescription 150 | * Repository description 151 | * @param addReadme 152 | * If true, initialize repository with a README 153 | * @param gitignore 154 | * Select gitignore from the dropdown 155 | * @param license 156 | * Select license type from the dropdown 157 | * 158 | * @return An instance of {@link RepositoryPage} class 159 | */ 160 | public RepositoryPage createRepository(String repName, 161 | String repDescription, boolean addReadme, String gitignore, 162 | String license) { 163 | // GitHub replaces all spaces to "-" anyway 164 | this.repName = repName.trim().replaceAll(" +", "-"); 165 | this.repNameElement.sendKeys(repName); 166 | this.repDescription.sendKeys(repDescription); 167 | if (autoInit.isSelected()) { 168 | if (!addReadme) { 169 | PageNavigator.click(driver, autoInit); 170 | } 171 | } else { 172 | if (addReadme) { 173 | PageNavigator.click(driver, autoInit); 174 | } 175 | } 176 | if (null != gitignore) { 177 | PageNavigator.click(driver, addGitignore); 178 | for (WebElement element : gitignoreList) { 179 | if (element.getText().contains(gitignore)) { 180 | element.click(); 181 | } 182 | } 183 | } 184 | if (null != license) { 185 | PageNavigator.click(driver, addLicense); 186 | for (WebElement element : licenseList) { 187 | if (element.getText().contains(license)) { 188 | element.click(); 189 | } 190 | } 191 | } 192 | repSubmit.click(); 193 | TestData data = TestData.getData(); 194 | data.setRepositoryName(repName); 195 | return PageFactory.initElements(driver, RepositoryPage.class); 196 | } 197 | 198 | /** 199 | * The method to get the repository name 200 | * 201 | * @return repName 202 | */ 203 | public String getRepositoryName() { 204 | return repName; 205 | } 206 | 207 | /** 208 | * Method to get expected page title 209 | * 210 | * @return expected page title 211 | */ 212 | @Override 213 | public String getExpectedTitle() { 214 | return "Create a New Repository"; 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /src/com/nat/test/pages/HomePage.java: -------------------------------------------------------------------------------- 1 | package com.nat.test.pages; 2 | 3 | import java.util.List; 4 | 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.support.FindBy; 8 | import org.openqa.selenium.support.PageFactory; 9 | 10 | /** 11 | * Class represents Home page that opens after successful login 12 | */ 13 | public class HomePage extends Page { 14 | 15 | @FindBy(name = "q") 16 | private WebElement search; 17 | 18 | @FindBy(xpath = "//*[contains(text(),'Welcome to GitHub!')]") 19 | private WebElement welcomeMessage; 20 | 21 | @FindBy(id = "user-links") 22 | private WebElement userLinks; 23 | 24 | @FindBy(id = "your_repos") 25 | private WebElement repositories; 26 | 27 | @FindBy(xpath = "//a[contains(@class, 'new-repo')]") 28 | private WebElement newRepoButton; 29 | 30 | @FindBy(xpath = "//div[contains(text(), 'was successfully deleted')]") 31 | private WebElement successDeletingMessage; 32 | 33 | @FindBy(xpath = "//span[@class='repo']") 34 | private List repoList; 35 | 36 | @FindBy(xpath = "//a[@href='/notifications']") 37 | private WebElement notificationsIcon; 38 | 39 | /** 40 | * Class constructor 41 | * 42 | * @param driver 43 | * The driver that will be used for navigation 44 | * @throws IllegalStateException 45 | * If it's not expected page 46 | */ 47 | public HomePage(WebDriver driver) { 48 | super(driver); 49 | } 50 | 51 | /** 52 | * Checks if the search field presents on the page 53 | * 54 | * @return true if search field presents on the page 55 | */ 56 | public boolean isSearchPresents() { 57 | return isElementPresents(search); 58 | } 59 | 60 | /** 61 | * Search on the site 62 | * 63 | * @param query 64 | * Search query 65 | * @return An instance of {@link SearchPage} class with search result 66 | */ 67 | public SearchPage search(String query) { 68 | search.clear(); 69 | search.sendKeys(query); 70 | search.submit(); 71 | return PageFactory.initElements(driver, SearchPage.class); 72 | } 73 | 74 | /** 75 | * Checks that login was successful 76 | * 77 | * @return true if welcome message, user links and logout icon presents on 78 | * the page 79 | */ 80 | public boolean isLoginSuccessed() { 81 | return isElementPresents(welcomeMessage) 82 | && isElementPresents(userLinks) 83 | && isElementPresents(repositories) 84 | && isElementPresents(logoutNewDesign); 85 | } 86 | 87 | /** 88 | * Checks that button for creating new repository presents on the page 89 | * 90 | * @return true if button for creating new repository presents on the page 91 | */ 92 | public boolean isNewRepoButtonPresents() { 93 | return isElementPresents(newRepoButton); 94 | } 95 | 96 | /** 97 | * Clicks the button for creating new repository 98 | * 99 | * @return An instance of {@link CreateRepositoryPage} class 100 | */ 101 | public CreateRepositoryPage createNewRepository() { 102 | newRepoButton.click(); 103 | return PageFactory.initElements(driver, CreateRepositoryPage.class); 104 | } 105 | 106 | /** 107 | * Check that repository was just successfully deleted 108 | * 109 | * @param repName 110 | * The name of deleted repository 111 | * @return true is message about successful deleting presents and if deleted 112 | * repository is not presented in the list of existing repositories 113 | */ 114 | public boolean isRepositoryJustDeleted(String repName) { 115 | boolean oldRepoDeleted = true; 116 | for (WebElement element : repoList) { 117 | if (element.getText().equals(repName)) { 118 | oldRepoDeleted = false; 119 | } 120 | } 121 | return isElementPresents(successDeletingMessage) && oldRepoDeleted; 122 | } 123 | 124 | /** 125 | * Checks if notifications icon presents on the page 126 | * 127 | * @return True if notifications icon presents on the page 128 | */ 129 | public boolean isNotificationsIconPresents() { 130 | return isElementPresents(notificationsIcon); 131 | } 132 | 133 | /** 134 | * Navigates to the Notifications page 135 | * 136 | * @return An instance of {@link NotificationsPage} class 137 | */ 138 | public NotificationsPage seeNotifications() { 139 | notificationsIcon.click(); 140 | return PageFactory.initElements(driver, NotificationsPage.class); 141 | } 142 | 143 | /** 144 | * Method to get expected page title 145 | * 146 | * @return expected page title 147 | */ 148 | @Override 149 | public String getExpectedTitle() { 150 | return "GitHub"; 151 | } 152 | 153 | } 154 | -------------------------------------------------------------------------------- /src/com/nat/test/pages/IssuePage.java: -------------------------------------------------------------------------------- 1 | package com.nat.test.pages; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | 7 | public class IssuePage extends RepositoryAbstractPage { 8 | 9 | @FindBy(id = "issue_title") 10 | private WebElement title; 11 | 12 | @FindBy(id = "issue_body") 13 | private WebElement comment; 14 | 15 | @FindBy(xpath = "//button[contains(text(), 'Submit new issue')]") 16 | private WebElement submitNewIssueBtn; 17 | 18 | @FindBy(xpath = "//time[contains(text(), 'just now')]") 19 | private WebElement timeJustAdded; 20 | 21 | @FindBy(xpath = "//div[contains(@class, 'state-open')]") 22 | private WebElement statusOpen; 23 | 24 | /** 25 | * Class constructor 26 | * 27 | * @param driver 28 | * The driver that will be used for navigation 29 | * @throws IllegalStateException 30 | * If it's not expected page 31 | */ 32 | public IssuePage(WebDriver driver) { 33 | super(driver); 34 | } 35 | 36 | public boolean areNewIssueElementsPresent() { 37 | return isElementPresents(title) && isElementPresents(comment) 38 | && isElementPresents(submitNewIssueBtn); 39 | } 40 | 41 | public IssuePage addIssue(String titleStr, String commentStr) { 42 | title.clear(); 43 | title.sendKeys(titleStr); 44 | comment.clear(); 45 | comment.sendKeys(commentStr); 46 | submitNewIssueBtn.click(); 47 | return this; 48 | 49 | } 50 | 51 | public boolean IsIssueJustAdded() { 52 | System.out.println("status " + statusOpen.getText()); 53 | return isElementPresents(timeJustAdded) 54 | && isElementPresents(statusOpen); 55 | } 56 | 57 | /** 58 | * Method to get expected page title 59 | * 60 | * @return expected page title 61 | */ 62 | @Override 63 | public String getExpectedTitle() { 64 | return "Issue"; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/com/nat/test/pages/IssuesSectionPage.java: -------------------------------------------------------------------------------- 1 | package com.nat.test.pages; 2 | 3 | import java.util.List; 4 | 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.support.FindBy; 8 | import org.openqa.selenium.support.PageFactory; 9 | 10 | public class IssuesSectionPage extends RepositoryAbstractPage { 11 | 12 | @FindBy(xpath = "//h3[text()='Welcome to Issues!']") 13 | private WebElement welcomeMessage; 14 | 15 | @FindBy(xpath = "//a[contains(text(), 'New issue')][contains(@class, 'btn-primary')]") 16 | private WebElement btnAddIssue; 17 | 18 | @FindBy(xpath = "//button[contains(text(), 'Filters')]") 19 | private WebElement filters; 20 | 21 | @FindBy(id = "js-issues-search") 22 | private WebElement searchField; 23 | 24 | @FindBy(xpath = "//ul[contains(@class, 'table-list-issues')]/li/div[2]/a") 25 | private List issuesList; 26 | 27 | /** 28 | * Class constructor 29 | * 30 | * @param driver 31 | * The driver that will be used for navigation 32 | * @throws IllegalStateException 33 | * If it's not expected page 34 | */ 35 | public IssuesSectionPage(WebDriver driver) { 36 | super(driver); 37 | } 38 | 39 | public boolean areAllElementsPresent() { 40 | return isElementPresents(btnAddIssue) && isElementPresents(filters) 41 | && isElementPresents(searchField); 42 | } 43 | 44 | public boolean isWelcomeMessagePresent() { 45 | return isElementPresents(welcomeMessage); 46 | } 47 | 48 | public IssuePage addNewIssue() { 49 | btnAddIssue.click(); 50 | return PageFactory.initElements(driver, IssuePage.class); 51 | } 52 | 53 | public boolean isIssuePresent(String title) { 54 | for (WebElement issue : issuesList) { 55 | if (issue.getText().equalsIgnoreCase(title)) { 56 | return true; 57 | } 58 | } 59 | return false; 60 | } 61 | 62 | /** 63 | * Method to get expected page title 64 | * 65 | * @return expected page title 66 | */ 67 | @Override 68 | public String getExpectedTitle() { 69 | return "Issues"; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/com/nat/test/pages/LoginPage.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natlg/Selenium-TestNG-Test-Framework/3783876644e781bb60db1512e1774b8a2810e00f/src/com/nat/test/pages/LoginPage.java -------------------------------------------------------------------------------- /src/com/nat/test/pages/NotificationsPage.java: -------------------------------------------------------------------------------- 1 | package com.nat.test.pages; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | 7 | /** 8 | * Class represents page with notifications 9 | */ 10 | public class NotificationsPage extends Page { 11 | 12 | @FindBy(partialLinkText = "Unread") 13 | private WebElement unread; 14 | 15 | @FindBy(partialLinkText = "Participating") 16 | private WebElement participating; 17 | 18 | @FindBy(linkText = "All notifications") 19 | private WebElement allNotifications; 20 | 21 | /** 22 | * Class constructor 23 | * 24 | * @param driver 25 | * The driver that will be used for navigation 26 | * @throws IllegalStateException 27 | * If it's not expected page 28 | */ 29 | public NotificationsPage(WebDriver driver) { 30 | super(driver); 31 | } 32 | 33 | /** 34 | * Method checks if all notification sections present 35 | * 36 | * @return True if Unread, Participating and All notifications sections 37 | * present 38 | */ 39 | public boolean isNoticicationsPresent() { 40 | return isElementPresents(unread) && isElementPresents(participating) 41 | && isElementPresents(allNotifications); 42 | } 43 | 44 | /** 45 | * Method to get expected page title 46 | * 47 | * @return expected page title 48 | */ 49 | @Override 50 | public String getExpectedTitle() { 51 | return "Notifications"; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/com/nat/test/pages/OptionsPage.java: -------------------------------------------------------------------------------- 1 | package com.nat.test.pages; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | import org.openqa.selenium.support.PageFactory; 7 | 8 | /** 9 | * Class represents page with Repository settings 10 | */ 11 | public class OptionsPage extends RepositoryAbstractPage { 12 | 13 | @FindBy(xpath = "//a[contains(@href, 'delete_repo_confirm')]") 14 | private WebElement delete; 15 | 16 | @FindBy(xpath = "//*[@id='facebox']/div/div/form/p/input") 17 | private WebElement deleteField; 18 | 19 | /** 20 | * Class constructor 21 | * 22 | * @param driver 23 | * The driver that will be used for navigation 24 | * @throws IllegalStateException 25 | * If it's not expected page 26 | */ 27 | public OptionsPage(WebDriver driver) { 28 | super(driver); 29 | } 30 | 31 | /** 32 | * Checks if delete option presents 33 | * 34 | * @return True if delete option presents 35 | */ 36 | public boolean isDeletePresents() { 37 | return isElementPresents(delete); 38 | } 39 | 40 | /** 41 | * Method to delete repository 42 | * 43 | * @param repName 44 | * repository name 45 | * 46 | * @return An instance of {@link HomePage} class 47 | */ 48 | public HomePage deleteRepository(String repName) { 49 | delete.click(); 50 | System.out.println(repName + " visible " 51 | + isElementPresents(deleteField)); 52 | deleteField.sendKeys(repName); 53 | deleteField.submit(); 54 | return PageFactory.initElements(driver, HomePage.class); 55 | } 56 | 57 | /** 58 | * Method to delete current repository 59 | * 60 | * @return An instance of {@link HomePage} class 61 | */ 62 | public HomePage deleteRepository() { 63 | delete.click(); 64 | deleteField.sendKeys(repNameElement.getText()); 65 | deleteField.submit(); 66 | return PageFactory.initElements(driver, HomePage.class); 67 | } 68 | 69 | /** 70 | * Method to get expected page title 71 | * 72 | * @return expected page title 73 | */ 74 | @Override 75 | public String getExpectedTitle() { 76 | // Here is a bug 77 | return null; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/com/nat/test/pages/Page.java: -------------------------------------------------------------------------------- 1 | package com.nat.test.pages; 2 | 3 | import org.openqa.selenium.NoSuchElementException; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.support.FindBy; 7 | import org.openqa.selenium.support.PageFactory; 8 | 9 | /** 10 | * Base class for all pages 11 | */ 12 | public abstract class Page { 13 | protected WebDriver driver; 14 | 15 | /** 16 | * Class constructor 17 | * 18 | * @param driver 19 | * The driver that will be used for navigation 20 | * @throws IllegalStateException 21 | * If it's not expected page 22 | */ 23 | public Page(WebDriver driver) { 24 | this.driver = driver; 25 | String title = driver.getTitle().trim(); 26 | String expTitle = (String) getExpectedTitle(); 27 | System.out.println("title: " + title + " exp title: " + expTitle); 28 | if (null != expTitle && !title.contains(expTitle)) { 29 | throw new IllegalStateException("This is not the " + expTitle 30 | + ", this is " + title); 31 | } 32 | } 33 | 34 | public abstract CharSequence getExpectedTitle(); 35 | 36 | /** 37 | * presents in new design 38 | */ 39 | @FindBy(xpath = "//button[contains(@class, 'sign-out-button')]") 40 | protected WebElement logoutNewDesign; 41 | 42 | @FindBy(name = "q") 43 | protected WebElement search; 44 | 45 | /** 46 | * presents in old design 47 | */ 48 | @FindBy(xpath = ".//*[@id='user-links']/li[3]/a/img") 49 | protected WebElement headerUserOldDesign; 50 | 51 | /** 52 | * presents in old design after clicking on {@link headerUserOldDesign} 53 | */ 54 | @FindBy(xpath = "//button[@class = 'sign-out-button']") 55 | protected WebElement logoutOldDesign; 56 | 57 | /** 58 | * Checks if the element presents on the page and visible 59 | * 60 | * @param element 61 | * element to check 62 | * 63 | * @return true if the element presents on the page and visible 64 | */ 65 | protected boolean isElementPresents(WebElement element) { 66 | try { 67 | return element.isDisplayed(); 68 | } catch (NoSuchElementException e) { 69 | return false; 70 | } 71 | } 72 | 73 | /** 74 | * The method to logout 75 | * 76 | * @return An instance of {@link Page} class after logout 77 | */ 78 | public Page logout() { 79 | if (isElementPresents(logoutNewDesign)) { 80 | logoutNewDesign.click(); 81 | return this; 82 | } else { 83 | System.out.println("headerUserOldDesign" 84 | + headerUserOldDesign.isDisplayed()); 85 | headerUserOldDesign.click(); 86 | System.out.println("logoutOldDesign" 87 | + logoutOldDesign.isDisplayed()); 88 | logoutOldDesign.click(); 89 | return this; 90 | } 91 | } 92 | 93 | /** 94 | * Method to search 95 | * 96 | * @param query 97 | * Search query 98 | * @return An instance of {@link Page} class with search result 99 | */ 100 | public Page search(String query) { 101 | search.clear(); 102 | search.sendKeys(query); 103 | search.submit(); 104 | return this; 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/com/nat/test/pages/RepositoryAbstractPage.java: -------------------------------------------------------------------------------- 1 | package com.nat.test.pages; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.support.FindBy; 7 | import org.openqa.selenium.support.PageFactory; 8 | 9 | /** 10 | * Base class for pages that contain functions for working with repository 11 | */ 12 | public abstract class RepositoryAbstractPage extends Page { 13 | 14 | @FindBy(xpath = "//a[contains(@class, 'current-repository')]") 15 | protected WebElement repNameElement; 16 | 17 | @FindBy(xpath = "//*[text()='Code']") 18 | protected WebElement code; 19 | 20 | @FindBy(xpath = "//span[text()='Issues']/..") 21 | protected WebElement issues; 22 | 23 | @FindBy(xpath = "//*[text()='Pull requests']") 24 | protected WebElement pullRequests; 25 | 26 | @FindBy(xpath = "//*[text()='Wiki']") 27 | protected WebElement wiki; 28 | 29 | @FindBy(xpath = "//*[text()='Pulse']") 30 | protected WebElement pulse; 31 | 32 | @FindBy(xpath = "//*[text()='Graphs']") 33 | protected WebElement graphs; 34 | 35 | @FindBy(xpath = "//a[contains (@data-selected-links, 'repo_settings')]") 36 | protected WebElement settings; 37 | 38 | protected String repName; 39 | 40 | public RepositoryAbstractPage(WebDriver driver) { 41 | super(driver); 42 | } 43 | 44 | /** 45 | * Check if all sections present on the page 46 | * 47 | * @return True if all sections present on the page 48 | */ 49 | public boolean areRepSectionsPresent() { 50 | return isElementPresents(repNameElement) && isElementPresents(code) 51 | && isElementPresents(issues) && isElementPresents(pullRequests) 52 | && isElementPresents(wiki) && isElementPresents(pulse) 53 | && isElementPresents(graphs) && isElementPresents(settings); 54 | } 55 | 56 | /** 57 | * Navigate to the page with repository settings 58 | * 59 | * @return An instance of {@link OptionsPage} class with repository settings 60 | */ 61 | public OptionsPage goToSettings() { 62 | settings.click(); 63 | return PageFactory.initElements(driver, OptionsPage.class); 64 | } 65 | 66 | /** 67 | * Navigate to the page with issues 68 | * 69 | * @return An instance of {@link IssuesSectionPage} class 70 | */ 71 | public IssuesSectionPage goToIssues() { 72 | issues.click(); 73 | System.out.println("Click issues " + issues.getText()); 74 | return PageFactory.initElements(driver, IssuesSectionPage.class); 75 | } 76 | 77 | /** 78 | * The method to get repository name 79 | * 80 | * @return repository name 81 | */ 82 | public String getRepositoryName() { 83 | return repNameElement.getText(); 84 | } 85 | 86 | /** 87 | * The method to set repository name 88 | * 89 | * @param repName 90 | * Repository name to set 91 | */ 92 | public void setRepName(String repName) { 93 | this.repName = repName; 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/com/nat/test/pages/RepositoryPage.java: -------------------------------------------------------------------------------- 1 | package com.nat.test.pages; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.support.FindBy; 6 | import org.openqa.selenium.support.PageFactory; 7 | 8 | import com.nat.test.TestData; 9 | 10 | /** 11 | * Class represents page with repository 12 | */ 13 | public class RepositoryPage extends RepositoryAbstractPage { 14 | 15 | private String repoName; 16 | 17 | /** 18 | * Class constructor 19 | * 20 | * @param driver 21 | * The driver that will be used for navigation 22 | * @throws IllegalStateException 23 | * If it's not expected page 24 | */ 25 | public RepositoryPage(WebDriver driver) { 26 | super(driver); 27 | } 28 | 29 | /** 30 | * Method to get expected page title 31 | * 32 | * @return expected page title 33 | */ 34 | @Override 35 | public String getExpectedTitle() { 36 | TestData data = TestData.getData(); 37 | repoName = data.getRepositoryName(); 38 | return TestData.LOGIN + "/" + repoName; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/com/nat/test/pages/SearchPage.java: -------------------------------------------------------------------------------- 1 | package com.nat.test.pages; 2 | 3 | import java.util.List; 4 | 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.support.FindBy; 8 | import org.openqa.selenium.support.PageFactory; 9 | 10 | import com.nat.test.TestData; 11 | 12 | /** 13 | * Class represents page with search results 14 | */ 15 | public class SearchPage extends Page { 16 | 17 | @FindBy(xpath = "//ul[@class='repo-list js-repo-list']/li/h3/a") 18 | private List searchResults; 19 | 20 | @FindBy(xpath = "//*[contains(text(), \"We couldn't find any repositories matching\")]") 21 | private WebElement errorNoResult; 22 | 23 | /** 24 | * Class constructor 25 | * 26 | * @param driver 27 | * The driver that will be used for navigation 28 | * @throws IllegalStateException 29 | * If it's not expected page 30 | */ 31 | public SearchPage(WebDriver driver) { 32 | super(driver); 33 | } 34 | 35 | /** 36 | * Method to get the list of links with search results 37 | * 38 | * @return List of links with search results 39 | */ 40 | public List getSearchResults() { 41 | return searchResults; 42 | } 43 | 44 | /** 45 | * Check if error message presents 46 | * 47 | * @return True if error message presents 48 | */ 49 | public boolean isErrorNoResultPresents() { 50 | return isElementPresents(errorNoResult); 51 | } 52 | 53 | /** 54 | * Method to get expected page title 55 | * 56 | * @return expected page title 57 | */ 58 | @Override 59 | public String getExpectedTitle() { 60 | return "Search"; 61 | } 62 | 63 | /** 64 | * Method to check if search results contain search query 65 | * 66 | * @param searchQuery 67 | * Search Query 68 | * 69 | * @return True if search results contain search query 70 | */ 71 | public boolean isResultContains(String searchQuery) { 72 | List searchResults = getSearchResults(); 73 | boolean contains = false; 74 | for (WebElement result : searchResults) { 75 | if (result.getAttribute("href").toLowerCase().contains(searchQuery)) { 76 | contains = true; 77 | } 78 | } 79 | return contains; 80 | } 81 | 82 | /** 83 | * Method to check if search results appear correct: if some results found, 84 | * they contain search query or if nothing found, error message appears 85 | * 86 | * @param hasResult 87 | * If true, search results must appear, if false, then error 88 | * message 89 | * @param searchQuery 90 | * Search Query 91 | * 92 | * @return True if search results appear correct: if some results found, 93 | * they contain search query or if nothing found, error message 94 | * appears 95 | */ 96 | public boolean isResultMatch(boolean hasResult, String searchQuery) { 97 | if (hasResult) { 98 | return isResultContains(searchQuery); 99 | } else { 100 | return isErrorNoResultPresents(); 101 | } 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/com/nat/test/pages/StartPage.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natlg/Selenium-TestNG-Test-Framework/3783876644e781bb60db1512e1774b8a2810e00f/src/com/nat/test/pages/StartPage.java -------------------------------------------------------------------------------- /src/com/nat/test/utils/ConfigReader.java: -------------------------------------------------------------------------------- 1 | package com.nat.test.utils; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.FileNotFoundException; 5 | import java.io.IOException; 6 | import java.util.Properties; 7 | 8 | /** 9 | * Class reads base settings from the config.properties file 10 | */ 11 | public class ConfigReader { 12 | private String login = ""; 13 | private String password = ""; 14 | private boolean useAssert = true; 15 | private String firefoxPath = ""; 16 | private String browser =""; 17 | 18 | /** 19 | * Class constructor loads settings from the file and saves to fields 20 | */ 21 | public ConfigReader() { 22 | FileInputStream fis; 23 | try { 24 | fis = new FileInputStream("data/config.properties"); 25 | } catch (FileNotFoundException e) { 26 | e.printStackTrace(); 27 | System.out.println("Cant't read config.properties file!"); 28 | return; 29 | } 30 | Properties p = new Properties(); 31 | try { 32 | p.load(fis); 33 | } catch (IOException e) { 34 | e.printStackTrace(); 35 | System.out.println("Cant't read config.properties file!"); 36 | return; 37 | } 38 | login = p.getProperty("LOGIN"); 39 | password = p.getProperty("PASSWORD"); 40 | browser = p.getProperty("BROWSER"); 41 | firefoxPath = p.getProperty("FIREFOX_PATH"); 42 | try { 43 | useAssert = Boolean.parseBoolean(p.getProperty("USE_ASSERT")); 44 | } catch (Exception e) { 45 | e.printStackTrace(); 46 | System.out.println("Can't read useAssert property"); 47 | } 48 | } 49 | 50 | /** 51 | * Method to get the path to Firefox profile 52 | * 53 | * @return firefoxPath 54 | */ 55 | public String getFirefoxPath() { 56 | return firefoxPath; 57 | } 58 | 59 | /** 60 | * Method to get the user name 61 | * 62 | * @return login 63 | */ 64 | public String getLogin() { 65 | return login; 66 | } 67 | 68 | /** 69 | * Method to get the Assert usage 70 | * 71 | * @return useAssert 72 | */ 73 | public boolean isUseAssert() { 74 | return useAssert; 75 | } 76 | 77 | /** 78 | * Method to get the password 79 | * 80 | * @return password 81 | */ 82 | public String getPassword() { 83 | return password; 84 | } 85 | 86 | public String getBrowser() { 87 | return browser; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/com/nat/test/utils/PageNavigator.java: -------------------------------------------------------------------------------- 1 | package com.nat.test.utils; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | import org.openqa.selenium.WebElement; 5 | import org.openqa.selenium.interactions.Actions; 6 | import org.openqa.selenium.support.PageFactory; 7 | 8 | import com.nat.test.TestData; 9 | import com.nat.test.pages.CreateRepositoryPage; 10 | import com.nat.test.pages.HomePage; 11 | import com.nat.test.pages.LoginPage; 12 | import com.nat.test.pages.OptionsPage; 13 | import com.nat.test.pages.Page; 14 | import com.nat.test.pages.RepositoryAbstractPage; 15 | import com.nat.test.pages.RepositoryPage; 16 | import com.nat.test.pages.SearchPage; 17 | import com.nat.test.pages.StartPage; 18 | 19 | /** 20 | * Class for navigation on the site 21 | */ 22 | public class PageNavigator { 23 | 24 | private StartPage startPage; 25 | private LoginPage loginPage; 26 | private HomePage homePage; 27 | private CreateRepositoryPage createRepositoryPage; 28 | private RepositoryPage repositoryPage; 29 | private OptionsPage optionsPage; 30 | 31 | /** 32 | * Navigate to the page with the login form. Need to sign out before 33 | * calling. Returns null if it's not possible to get the Login page 34 | * 35 | * @param driver 36 | * The driver that will be used for navigation 37 | * @return An instance of {@link LoginPage} class or null if it's not 38 | * possible to get the Login page 39 | */ 40 | public LoginPage getLoginPage(WebDriver driver) { 41 | loginPage = null; 42 | driver.get(TestData.BASE_URL); 43 | try { 44 | startPage = PageFactory.initElements(driver, StartPage.class); 45 | loginPage = startPage.navigateToLogin(); 46 | } catch (Exception e) { 47 | e.printStackTrace(); 48 | System.out.println("Can't get the Login page"); 49 | } 50 | return loginPage; 51 | } 52 | 53 | /** 54 | * Login with correct data (takes username and password from the 55 | * config.properties file) and navigate to the Home page. Need to sign out 56 | * before calling. Returns null if it's not possible to login or get the 57 | * Home page 58 | * 59 | * @param driver 60 | * The driver that will be used for navigation 61 | * @return An instance of {@link HomePage} class or null if it's not 62 | * possible to login or get the Home page 63 | */ 64 | public HomePage login(WebDriver driver) { 65 | homePage = null; 66 | try { 67 | LoginPage loginPage = getLoginPage(driver); 68 | homePage = loginPage.loginAs(TestData.LOGIN, TestData.PASSWORD); 69 | } catch (Exception e) { 70 | e.printStackTrace(); 71 | System.out.println("Can't get the Home page"); 72 | } 73 | return homePage; 74 | } 75 | 76 | /** 77 | * Method to get the page with just created repository. Need to sign out 78 | * before calling. Returns null if it's not possible to get the Repository 79 | * page 80 | * 81 | * @param driver 82 | * The driver that will be used for navigation 83 | * @param repDescription 84 | * Repository description 85 | * @param addReadme 86 | * If true, initialize repository with a README 87 | * @param gitignore 88 | * Select gitignore from the dropdown 89 | * @param license 90 | * Select license type from the dropdown 91 | * 92 | * @return An instance of {@link RepositoryPage} class or null if it's not 93 | * possible to login or get the Repository page 94 | */ 95 | public RepositoryPage getNewRepositoryPage(WebDriver driver, 96 | String repDescription, boolean addReadme, String gitignore, 97 | String license) { 98 | repositoryPage = null; 99 | try { 100 | driver.get(TestData.BASE_URL); 101 | homePage = login(driver); 102 | createRepositoryPage = homePage.createNewRepository(); 103 | String currentRepName = getUniqueRepName(); 104 | repositoryPage = createRepositoryPage.createRepository( 105 | currentRepName, repDescription, addReadme, gitignore, 106 | license); 107 | 108 | } catch (Exception e) { 109 | e.printStackTrace(); 110 | System.out.println("Can't get RepositoryPage"); 111 | } 112 | return repositoryPage; 113 | } 114 | 115 | /** 116 | * The method to get the unique name for new repository 117 | * 118 | * @return unique name 119 | */ 120 | public String getUniqueRepName() { 121 | return "NewRepository" + System.currentTimeMillis(); 122 | } 123 | 124 | /** 125 | * Method to log out and get Start page from any page. Ren null if it's not 126 | * possible to log out or get the Start page 127 | * 128 | * @param driver 129 | * The driver that will be used for navigation 130 | * @param page 131 | * Current page 132 | * @return An instance of {@link StartPage} class or null if it's not 133 | * possible to log out or get the Start page 134 | */ 135 | public StartPage logout(WebDriver driver, Page page) { 136 | try { 137 | page.logout(); 138 | driver.get(TestData.BASE_URL); 139 | startPage = PageFactory.initElements(driver, StartPage.class); 140 | return startPage; 141 | } catch (Exception e) { 142 | e.printStackTrace(); 143 | System.out.println("Can't get Start page"); 144 | return null; 145 | } 146 | 147 | } 148 | 149 | /** 150 | * Method to search 151 | * 152 | * @param driver 153 | * The driver that will be used for navigation 154 | * @param query 155 | * Search query 156 | * @param page 157 | * Current page 158 | * @return An instance of {@link SearchPage} class with search result 159 | */ 160 | public SearchPage search(WebDriver driver, String query, Page page) { 161 | page.search(query); 162 | return PageFactory.initElements(driver, SearchPage.class); 163 | } 164 | 165 | /** 166 | * Method to perform click using {@link Actions} class. Call if simple click 167 | * doesn't work for {@link ChromeDriver} 168 | * 169 | * @param driver 170 | * The driver that will be used for navigation 171 | * @param element 172 | * Element to click 173 | */ 174 | public static void click(WebDriver driver, WebElement element) { 175 | try { 176 | element.click(); 177 | } catch (org.openqa.selenium.WebDriverException e) { 178 | Actions action = new Actions(driver); 179 | action.moveToElement(element).perform(); 180 | action.click().perform(); 181 | } 182 | } 183 | 184 | /** 185 | * Method to delete repository 186 | * 187 | * @param driver 188 | * The driver that will be used for navigation 189 | * @param page 190 | * Page with repository to delete 191 | * @return An instance of {@link HomePage} class 192 | */ 193 | public HomePage deleteRepository(WebDriver driver, 194 | RepositoryAbstractPage page) { 195 | optionsPage = page.goToSettings(); 196 | homePage = optionsPage.deleteRepository(); 197 | return homePage; 198 | } 199 | 200 | /** 201 | * Method to delete repository and then logout 202 | * 203 | * @param driver 204 | * The driver that will be used for navigation 205 | * @param page 206 | * Page with repository to delete 207 | * @return An instance of {@link HomePage} class 208 | */ 209 | public StartPage deleteRepositiryAndLogout(WebDriver driver, 210 | String repName, RepositoryPage repositoryPage) { 211 | optionsPage = repositoryPage.goToSettings(); 212 | homePage = optionsPage.deleteRepository(repName); 213 | return logout(driver, repositoryPage); 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /src/com/nat/test/utils/XLSWorker.java: -------------------------------------------------------------------------------- 1 | package com.nat.test.utils; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.FileNotFoundException; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.util.ArrayList; 8 | import java.util.Calendar; 9 | import java.util.List; 10 | 11 | import org.apache.poi.hssf.usermodel.HSSFCellStyle; 12 | import org.apache.poi.hssf.usermodel.HSSFDateUtil; 13 | import org.apache.poi.hssf.util.HSSFColor; 14 | import org.apache.poi.ss.usermodel.Cell; 15 | import org.apache.poi.ss.usermodel.CellStyle; 16 | import org.apache.poi.ss.usermodel.IndexedColors; 17 | import org.apache.poi.ss.usermodel.Row; 18 | import org.apache.poi.xssf.usermodel.XSSFCell; 19 | import org.apache.poi.xssf.usermodel.XSSFCellStyle; 20 | import org.apache.poi.xssf.usermodel.XSSFCreationHelper; 21 | import org.apache.poi.xssf.usermodel.XSSFFont; 22 | import org.apache.poi.xssf.usermodel.XSSFHyperlink; 23 | import org.apache.poi.xssf.usermodel.XSSFRow; 24 | import org.apache.poi.xssf.usermodel.XSSFSheet; 25 | import org.apache.poi.xssf.usermodel.XSSFWorkbook; 26 | 27 | import com.nat.test.pages.SearchPage; 28 | 29 | /** 30 | * Class provides work with excel files 31 | */ 32 | public class XLSWorker { 33 | 34 | private String path; 35 | private FileInputStream fis = null; 36 | private FileOutputStream fos = null; 37 | private XSSFWorkbook workbook = null; 38 | private XSSFSheet sheet = null; 39 | private XSSFRow row = null; 40 | private XSSFCell cell = null; 41 | 42 | /** 43 | * Class constructor 44 | * 45 | * @param path 46 | * Path to the excel file 47 | */ 48 | public XLSWorker(String path) { 49 | 50 | this.path = path; 51 | try { 52 | fis = new FileInputStream(path); 53 | workbook = new XSSFWorkbook(fis); 54 | sheet = workbook.getSheetAt(0); 55 | fis.close(); 56 | } catch (Exception e) { 57 | e.printStackTrace(); 58 | System.out.println("Didn't find file " + path); 59 | } 60 | } 61 | 62 | /** 63 | * Read data in the TestData sheet. For the correct work there must be empty 64 | * row between different test case data in the file 65 | * 66 | * @param testCase 67 | * Test Case name as it's in the file 68 | * @return Two dimensional array with data from 2 columns to the right of 69 | * Test Case name 70 | */ 71 | public String[][] getDataForTest(String testCase) throws Exception { 72 | 73 | // Get sheet 74 | String sheetName = "TestData"; 75 | int index = workbook.getSheetIndex(sheetName); 76 | XSSFSheet sheet = workbook.getSheetAt(index); 77 | 78 | // Find row num with test case 79 | int rowNum = -1; 80 | for (int i = 0; i <= sheet.getLastRowNum(); i++) { 81 | Row row = sheet.getRow(i); 82 | if (row.getCell(0).getStringCellValue().equals(testCase)) { 83 | rowNum = i; 84 | break; 85 | } 86 | } 87 | if (rowNum == -1) { 88 | throw new IllegalArgumentException( 89 | "Can't find test case with the name " + testCase); 90 | } 91 | 92 | // Fill list with data till empty cell (array) 93 | List data = new ArrayList<>(); 94 | for (int i = rowNum; i <= sheet.getLastRowNum(); i++) { 95 | Row row = sheet.getRow(i); 96 | if (row.getCell(1).getStringCellValue().isEmpty()) { 97 | break; 98 | } 99 | 100 | String[] rowData = new String[2]; 101 | rowData[0] = row.getCell(1).getStringCellValue(); 102 | rowData[1] = row.getCell(2).getStringCellValue(); 103 | data.add(rowData); 104 | } 105 | 106 | // Move list to array 107 | String[][] array = new String[data.size()][]; 108 | for (int i = 0; i < data.size(); i++) { 109 | array[i] = data.get(i); 110 | } 111 | return array; 112 | } 113 | 114 | /** 115 | * Read data in the cell 116 | * 117 | * @param sheetName 118 | * Sheet name 119 | * @param colName 120 | * Column name 121 | * @param rowNum 122 | * Row number 123 | * @return Data in the cell 124 | */ 125 | public String getCellData(String sheetName, String colName, int rowNum) { 126 | try { 127 | if (rowNum <= 0) 128 | return ""; 129 | 130 | int index = workbook.getSheetIndex(sheetName); 131 | int colNum = -1; 132 | if (index == -1) 133 | return ""; 134 | sheet = workbook.getSheetAt(index); 135 | row = sheet.getRow(0); 136 | for (int i = 0; i < row.getLastCellNum(); i++) { 137 | if (row.getCell(i).getStringCellValue().trim() 138 | .equals(colName.trim())) 139 | colNum = i; 140 | } 141 | if (colNum == -1) 142 | return ""; 143 | sheet = workbook.getSheetAt(index); 144 | row = sheet.getRow(rowNum - 1); 145 | if (row == null) 146 | return ""; 147 | cell = row.getCell(colNum); 148 | if (cell == null) 149 | return ""; 150 | return cell.getStringCellValue(); 151 | } catch (Exception e) { 152 | e.printStackTrace(); 153 | return ""; 154 | } 155 | } 156 | 157 | /** 158 | * Read data in the cell 159 | * 160 | * @param sheetName 161 | * Sheet name 162 | * @param colNum 163 | * Column number 164 | * @param rowNum 165 | * Row number 166 | * @return Data in the cell 167 | */ 168 | public String getCellData(String sheetName, int colNum, int rowNum) { 169 | try { 170 | if (rowNum <= 0) 171 | return ""; 172 | int index = workbook.getSheetIndex(sheetName); 173 | if (index == -1) 174 | return ""; 175 | sheet = workbook.getSheetAt(index); 176 | row = sheet.getRow(rowNum - 1); 177 | if (row == null) 178 | return ""; 179 | cell = row.getCell(colNum); 180 | if (cell == null) { 181 | return ""; 182 | } 183 | return cell.getStringCellValue(); 184 | } catch (Exception e) { 185 | e.printStackTrace(); 186 | return ""; 187 | } 188 | } 189 | 190 | /** 191 | * Set data to the cell 192 | * 193 | * @param sheetName 194 | * Sheet name 195 | * @param colName 196 | * Column name 197 | * @param rowNum 198 | * Row number 199 | * @param data 200 | * Data 201 | * @return True if set the data successfully 202 | */ 203 | public boolean setCellData(String sheetName, String colName, int rowNum, 204 | String data) { 205 | try { 206 | fis = new FileInputStream(path); 207 | workbook = new XSSFWorkbook(fis); 208 | if (rowNum <= 0) 209 | return false; 210 | int index = workbook.getSheetIndex(sheetName); 211 | int colNum = -1; 212 | if (index == -1) 213 | return false; 214 | sheet = workbook.getSheetAt(index); 215 | row = sheet.getRow(0); 216 | for (int i = 0; i < row.getLastCellNum(); i++) { 217 | if (row.getCell(i).getStringCellValue().trim().equals(colName)) 218 | colNum = i; 219 | } 220 | if (colNum == -1) 221 | return false; 222 | sheet.autoSizeColumn(colNum); 223 | row = sheet.getRow(rowNum - 1); 224 | if (row == null) 225 | row = sheet.createRow(rowNum - 1); 226 | cell = row.getCell(colNum); 227 | if (cell == null) 228 | cell = row.createCell(colNum); 229 | cell.setCellValue(data); 230 | fos = new FileOutputStream(path); 231 | workbook.write(fos); 232 | fos.close(); 233 | } catch (Exception e) { 234 | e.printStackTrace(); 235 | return false; 236 | } 237 | return true; 238 | } 239 | 240 | /** 241 | * Set data to the cell 242 | * 243 | * @param sheetName 244 | * Sheet name 245 | * @param testCase 246 | * Test case 247 | * @param data 248 | * Data used in the test 249 | * @param result 250 | * Result 251 | * @return True if set the data successfully 252 | */ 253 | public boolean setCellData(String sheetName, String testCase, String data, 254 | String result) { 255 | try { 256 | // Get sheet 257 | int index = workbook.getSheetIndex(sheetName); 258 | XSSFSheet sheet = workbook.getSheetAt(index); 259 | 260 | // Find row num with test case 261 | int rowNum = -1; 262 | for (int i = 0; i <= sheet.getLastRowNum(); i++) { 263 | Row row = sheet.getRow(i); 264 | if (row.getCell(0).getStringCellValue().equals(testCase)) { 265 | rowNum = i; 266 | break; 267 | } 268 | } 269 | if (rowNum == -1) { 270 | throw new IllegalArgumentException( 271 | "Can't find test case with the name " + testCase); 272 | } 273 | 274 | // Find row num with data and save test result 275 | for (int i = rowNum; i <= sheet.getLastRowNum(); i++) { 276 | row = sheet.getRow(i); 277 | if (row.getCell(1).getStringCellValue().isEmpty()) { 278 | break; 279 | } 280 | if (row.getCell(1).getStringCellValue().equalsIgnoreCase(data)) { 281 | cell = row.getCell(3); 282 | cell.setCellValue(result); 283 | } 284 | } 285 | 286 | fos = new FileOutputStream(path); 287 | workbook.write(fos); 288 | fos.close(); 289 | } catch (FileNotFoundException e) { 290 | e.printStackTrace(); 291 | System.out.println("Didn't find file " + path); 292 | return false; 293 | } catch (IOException e) { 294 | e.printStackTrace(); 295 | System.out.println("Can't write data!"); 296 | return false; 297 | } 298 | return true; 299 | } 300 | } 301 | -------------------------------------------------------------------------------- /xls/TestCases.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natlg/Selenium-TestNG-Test-Framework/3783876644e781bb60db1512e1774b8a2810e00f/xls/TestCases.xlsx --------------------------------------------------------------------------------