├── README.md ├── dotnet ├── .gitignore ├── GitHubAutomation.sln └── GitHubAutomation │ ├── Driver │ └── DriverInstance.cs │ ├── DriverBinaries │ └── geckodriver.exe │ ├── GitHubAutomation.csproj │ ├── Pages │ ├── CreateNewRepositoryPage.cs │ ├── LoginPage.cs │ └── MainPage.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── Steps │ └── Steps.cs │ ├── Tests │ └── SmokeTests.cs │ ├── Utils │ └── RandomGenerator.cs │ └── packages.config └── java ├── .gitignore └── GitHubAutomation ├── pom.xml └── src └── test ├── java └── com │ └── epam │ └── ta │ ├── driver │ └── DriverSingleton.java │ ├── model │ └── User.java │ ├── page │ ├── AbstractPage.java │ ├── CreateNewRepositoryPage.java │ ├── LoginPage.java │ └── MainPage.java │ ├── service │ ├── TestDataReader.java │ └── UserCreator.java │ ├── test │ ├── CommonConditions.java │ ├── RepositoryManagementTests.java │ └── UserAccessTests.java │ └── util │ ├── StringUtils.java │ └── TestListener.java └── resources ├── dev.properties ├── log4j2.xml ├── qa.properties ├── staging.properties ├── testng-all.xml └── testng-smoke.xml /README.md: -------------------------------------------------------------------------------- 1 | github automation 2 | ================= 3 | 4 | C# and Java WebDriver test automation project for GitHub 5 | 6 | Java 7 | ==== 8 | 9 | Run from command line: mvn -Dbrowser=chrome -Dsurefire.suiteXmlFiles=src\test\resources\testng-smoke.xml -Denvironment=dev clean test 10 | -------------------------------------------------------------------------------- /dotnet/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | [Dd]ebug/ 11 | [Dd]ebugPublic/ 12 | [Rr]elease/ 13 | [Rr]eleases/ 14 | x64/ 15 | build/ 16 | bld/ 17 | [Bb]in/ 18 | [Oo]bj/ 19 | 20 | # NuGet Packages 21 | packages/* 22 | *.nupkg -------------------------------------------------------------------------------- /dotnet/GitHubAutomation.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Express 2012 for Windows Desktop 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHubAutomation", "GitHubAutomation\GitHubAutomation.csproj", "{C2708C88-282C-4AAB-8205-E24897FF2A67}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {C2708C88-282C-4AAB-8205-E24897FF2A67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {C2708C88-282C-4AAB-8205-E24897FF2A67}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {C2708C88-282C-4AAB-8205-E24897FF2A67}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {C2708C88-282C-4AAB-8205-E24897FF2A67}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /dotnet/GitHubAutomation/Driver/DriverInstance.cs: -------------------------------------------------------------------------------- 1 | using OpenQA.Selenium; 2 | using System; 3 | using OpenQA.Selenium.Firefox; 4 | using System.Diagnostics; 5 | 6 | namespace GitHubAutomation.Driver 7 | { 8 | public class DriverInstance 9 | { 10 | private static IWebDriver driver; 11 | 12 | private DriverInstance() { } 13 | 14 | public static IWebDriver GetInstance() 15 | { 16 | if (driver == null) 17 | { 18 | driver = new FirefoxDriver(); 19 | driver.Manage().Timeouts().ImplicitWait.Add(TimeSpan.FromSeconds(30)); 20 | driver.Manage().Window.Maximize(); 21 | } 22 | return driver; 23 | } 24 | 25 | public static void CloseBrowser() 26 | { 27 | driver.Quit(); 28 | driver = null; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /dotnet/GitHubAutomation/DriverBinaries/geckodriver.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitalliuss/github-automation/a061f7e974d3b8896f2b3d10a69a3d490caa4c70/dotnet/GitHubAutomation/DriverBinaries/geckodriver.exe -------------------------------------------------------------------------------- /dotnet/GitHubAutomation/GitHubAutomation.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | {C2708C88-282C-4AAB-8205-E24897FF2A67} 9 | Library 10 | Properties 11 | GitHubAutomation 12 | GitHubAutomation 13 | v4.5 14 | 512 15 | 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | ..\packages\NUnit.3.11.0\lib\net45\nunit.framework.dll 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | ..\packages\Selenium.WebDriver.3.141.0\lib\net45\WebDriver.dll 50 | 51 | 52 | ..\packages\Selenium.Support.3.141.0\lib\net45\WebDriver.Support.dll 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 79 | 80 | 81 | 82 | 89 | -------------------------------------------------------------------------------- /dotnet/GitHubAutomation/Pages/CreateNewRepositoryPage.cs: -------------------------------------------------------------------------------- 1 | using OpenQA.Selenium; 2 | using OpenQA.Selenium.Support.PageObjects; 3 | 4 | namespace GitHubAutomation.Pages 5 | { 6 | public class CreateNewRepositoryPage 7 | { 8 | private const string BASE_URL = "http://www.github.com/new"; 9 | private IWebDriver driver; 10 | 11 | [FindsBy(How = How.Id, Using = "repository_name")] 12 | private IWebElement inputRepositoryName; 13 | 14 | [FindsBy(How = How.Id, Using = "repository_description")] 15 | private IWebElement inputRepositoryDescription; 16 | 17 | [FindsBy(How = How.XPath, Using = "//form[@id='new_repository']//button[@type='submit']")] 18 | private IWebElement butttonCreate; 19 | 20 | [FindsBy(How = How.ClassName, Using = "//h3/strong[text()='Quick setup']")] 21 | private IWebElement labelEmptyRepoRecommendations; 22 | 23 | [FindsBy(How = How.XPath, Using = "//a[@data-pjax='#js-repo-pjax-container']")] 24 | private IWebElement linkCurrentRepository; 25 | 26 | 27 | public CreateNewRepositoryPage(IWebDriver driver) 28 | { 29 | this.driver = driver; 30 | PageFactory.InitElements(this.driver, this); 31 | } 32 | 33 | public void OpenPage() 34 | { 35 | driver.Navigate().GoToUrl(BASE_URL); 36 | } 37 | 38 | public void CreateNewRepository(string repositoryName, string repositoryDescription) 39 | { 40 | inputRepositoryName.SendKeys(repositoryName); 41 | inputRepositoryDescription.SendKeys(repositoryDescription); 42 | butttonCreate.Click(); 43 | } 44 | 45 | public bool IsCurrentRepositoryEmpty() 46 | { 47 | return labelEmptyRepoRecommendations.Displayed; 48 | } 49 | 50 | public string GetCurrentRepositoryName() 51 | { 52 | return linkCurrentRepository.Text; 53 | } 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /dotnet/GitHubAutomation/Pages/LoginPage.cs: -------------------------------------------------------------------------------- 1 | using OpenQA.Selenium; 2 | using OpenQA.Selenium.Support.PageObjects; 3 | using System; 4 | 5 | namespace GitHubAutomation.Pages 6 | { 7 | public class LoginPage 8 | { 9 | private const string BASE_URL = "https://github.com/login"; 10 | 11 | [FindsBy(How = How.Id, Using = "login_field")] 12 | private IWebElement inputLogin; 13 | 14 | [FindsBy(How = How.Id, Using = "password")] 15 | private IWebElement inputPassword; 16 | 17 | [FindsBy(How = How.XPath, Using = "//input[@value='Sign in']")] 18 | private IWebElement buttonSubmit; 19 | 20 | [FindsBy(How = How.XPath, Using = "//meta[@name='user-login']")] 21 | private IWebElement linkLoggedInUser; 22 | 23 | private IWebDriver driver; 24 | 25 | public LoginPage(IWebDriver driver) 26 | { 27 | this.driver = driver; 28 | PageFactory.InitElements(this.driver, this); 29 | } 30 | 31 | public void OpenPage() 32 | { 33 | driver.Navigate().GoToUrl(BASE_URL); 34 | Console.WriteLine("Login Page opened"); 35 | } 36 | 37 | public void Login(string username, string password) 38 | { 39 | inputLogin.SendKeys(username); 40 | inputPassword.SendKeys(password); 41 | buttonSubmit.Click(); 42 | } 43 | 44 | public string GetLoggedInUserName() 45 | { 46 | return linkLoggedInUser.GetAttribute("content"); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /dotnet/GitHubAutomation/Pages/MainPage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using OpenQA.Selenium.Support.PageObjects; 7 | using OpenQA.Selenium; 8 | 9 | namespace GitHubAutomation.Pages 10 | { 11 | public class MainPage 12 | { 13 | private const string BASE_URL = "http://www.github.com/"; 14 | 15 | [FindsBy(How = How.XPath, Using = "//summary[@aria-label='Create new…']")] 16 | private IWebElement buttonCreateNew; 17 | 18 | [FindsBy(How = How.XPath, Using = "//a[contains(text(), 'New repository')]")] 19 | private IWebElement linkNewRepository; 20 | 21 | private IWebDriver driver; 22 | 23 | public MainPage(IWebDriver driver) 24 | { 25 | this.driver = driver; 26 | PageFactory.InitElements(this.driver, this); 27 | } 28 | 29 | public void OpenPage() 30 | { 31 | driver.Navigate().GoToUrl(BASE_URL); 32 | } 33 | 34 | public void ClickOnCreateNewRepositoryButton() 35 | { 36 | buttonCreateNew.Click(); 37 | linkNewRepository.Click(); 38 | } 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /dotnet/GitHubAutomation/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("WebDriverDemo")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("EPAM Systems")] 12 | [assembly: AssemblyProduct("WebDriverDemo")] 13 | [assembly: AssemblyCopyright("Copyright © EPAM Systems 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8f0550ed-77c8-42ce-97c1-d587819fcd42")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /dotnet/GitHubAutomation/Steps/Steps.cs: -------------------------------------------------------------------------------- 1 | using OpenQA.Selenium; 2 | 3 | namespace GitHubAutomation.Steps 4 | { 5 | public class Steps 6 | { 7 | IWebDriver driver; 8 | 9 | public void InitBrowser() 10 | { 11 | driver = Driver.DriverInstance.GetInstance(); 12 | } 13 | 14 | public void CloseBrowser() 15 | { 16 | Driver.DriverInstance.CloseBrowser(); 17 | } 18 | 19 | public void LoginGithub(string username, string password) 20 | { 21 | Pages.LoginPage loginPage = new Pages.LoginPage(driver); 22 | loginPage.OpenPage(); 23 | loginPage.Login(username, password); 24 | } 25 | 26 | public string GetLoggedInUserName() 27 | { 28 | Pages.LoginPage loginPage = new Pages.LoginPage(driver); 29 | return loginPage.GetLoggedInUserName(); 30 | } 31 | 32 | public void CreateNewRepository(string repositoryName, string repositoryDescription) 33 | { 34 | Pages.MainPage mainPage = new Pages.MainPage(driver); 35 | mainPage.ClickOnCreateNewRepositoryButton(); 36 | Pages.CreateNewRepositoryPage createNewRepositoryPage = new Pages.CreateNewRepositoryPage(driver); 37 | createNewRepositoryPage.CreateNewRepository(repositoryName, repositoryDescription); 38 | } 39 | 40 | public string GenerateRandomRepositoryNameWithCharLength(int howManyChars) 41 | { 42 | string repositoryNamePrefix = "testRepo_"; 43 | return string.Concat(repositoryNamePrefix, Utils.RandomGenerator.GetRandomString(howManyChars)); 44 | } 45 | 46 | public bool CurrentRepositoryIsEmpty() 47 | { 48 | Pages.CreateNewRepositoryPage createNewRepositoryPage = new Pages.CreateNewRepositoryPage(driver); 49 | return createNewRepositoryPage.IsCurrentRepositoryEmpty(); 50 | } 51 | 52 | public string GetCurrentRepositoryName() 53 | { 54 | Pages.CreateNewRepositoryPage createNewRepositoryPage = new Pages.CreateNewRepositoryPage(driver); 55 | return createNewRepositoryPage.GetCurrentRepositoryName(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /dotnet/GitHubAutomation/Tests/SmokeTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace GitHubAutomation 4 | { 5 | [TestFixture] 6 | public class SmokeTests 7 | { 8 | private Steps.Steps steps = new Steps.Steps(); 9 | private const string USERNAME = "testautomationuser"; 10 | private const string PASSWORD = "Time4Death!"; 11 | private const int REPOSITORY_RANDOM_POSTFIX_LENGTH = 6; 12 | 13 | [SetUp] 14 | public void Init() 15 | { 16 | steps.InitBrowser(); 17 | } 18 | 19 | [TearDown] 20 | public void Cleanup() 21 | { 22 | steps.CloseBrowser(); 23 | } 24 | 25 | [Test] 26 | public void OneCanLoginGithub() 27 | { 28 | steps.LoginGithub(USERNAME, PASSWORD); 29 | Assert.AreEqual(USERNAME, steps.GetLoggedInUserName()); 30 | } 31 | 32 | [Test] 33 | public void OneCanCreateProject() 34 | { 35 | steps.LoginGithub(USERNAME, PASSWORD); 36 | string repositoryName = steps.GenerateRandomRepositoryNameWithCharLength(REPOSITORY_RANDOM_POSTFIX_LENGTH); 37 | steps.CreateNewRepository(repositoryName, "auto-generated test repo"); 38 | Assert.AreEqual(repositoryName, steps.GetCurrentRepositoryName()); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /dotnet/GitHubAutomation/Utils/RandomGenerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace GitHubAutomation.Utils 8 | { 9 | public class RandomGenerator 10 | { 11 | public static string GetRandomString(int length) 12 | { 13 | string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 14 | Random random = new Random(); 15 | string result = new string( 16 | Enumerable.Repeat(chars, length) 17 | .Select(s => s[random.Next(s.Length)]) 18 | .ToArray()); 19 | 20 | return result; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dotnet/GitHubAutomation/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /java/.gitignore: -------------------------------------------------------------------------------- 1 | # Java files 2 | *.class 3 | 4 | # Package Files # 5 | *.jar 6 | *.war 7 | *.ear 8 | target/ 9 | test-output/ 10 | 11 | # Eclipse 12 | .classpath 13 | .project 14 | .settings/ 15 | 16 | # Idea 17 | .idea/ 18 | *.iml -------------------------------------------------------------------------------- /java/GitHubAutomation/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.epam.ta 5 | github-automation 6 | jar 7 | 1.0 8 | GitHubAutomation 9 | http://maven.apache.org 10 | 11 | UTF-8 12 | 13 | 14 | 15 | 16 | org.seleniumhq.selenium 17 | selenium-java 18 | 3.141.0 19 | 20 | 21 | io.github.bonigarcia 22 | webdrivermanager 23 | 3.3.0 24 | test 25 | 26 | 27 | org.testng 28 | testng 29 | 6.14.3 30 | 31 | 32 | org.hamcrest 33 | hamcrest 34 | 2.1 35 | test 36 | 37 | 38 | commons-io 39 | commons-io 40 | 2.6 41 | 42 | 43 | org.apache.logging.log4j 44 | log4j-api 45 | 2.11.1 46 | 47 | 48 | org.apache.logging.log4j 49 | log4j-core 50 | 2.11.1 51 | 52 | 53 | 54 | 55 | 56 | org.apache.maven.plugins 57 | maven-surefire-plugin 58 | 2.22.1 59 | 60 | 61 | org.apache.maven.plugins 62 | maven-compiler-plugin 63 | 64 | 8 65 | 8 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/java/com/epam/ta/driver/DriverSingleton.java: -------------------------------------------------------------------------------- 1 | package com.epam.ta.driver; 2 | 3 | import io.github.bonigarcia.wdm.WebDriverManager; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.chrome.ChromeDriver; 6 | import org.openqa.selenium.firefox.FirefoxDriver; 7 | 8 | public class DriverSingleton { 9 | 10 | private static WebDriver driver; 11 | 12 | 13 | private DriverSingleton(){} 14 | 15 | public static WebDriver getDriver(){ 16 | if (null == driver){ 17 | switch (System.getProperty("browser")){ 18 | case "firefox": { 19 | WebDriverManager.firefoxdriver().setup(); 20 | driver = new FirefoxDriver(); 21 | } 22 | default: { 23 | WebDriverManager.chromedriver().setup(); 24 | driver = new ChromeDriver(); 25 | } 26 | } 27 | driver.manage().window().maximize(); 28 | } 29 | return driver; 30 | } 31 | 32 | public static void closeDriver(){ 33 | driver.quit(); 34 | driver = null; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/java/com/epam/ta/model/User.java: -------------------------------------------------------------------------------- 1 | package com.epam.ta.model; 2 | 3 | import java.util.Objects; 4 | 5 | public class User { 6 | 7 | private String username; 8 | private String password; 9 | 10 | 11 | public User(String username, String password) { 12 | this.username = username; 13 | this.password = password; 14 | } 15 | 16 | public String getUsername() { 17 | return username; 18 | } 19 | 20 | public void setUsername(String username) { 21 | this.username = username; 22 | } 23 | 24 | public String getPassword() { 25 | return password; 26 | } 27 | 28 | public void setPassword(String password) { 29 | this.password = password; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "User{" + 35 | "username='" + username + '\'' + 36 | ", password='" + password + '\'' + 37 | '}'; 38 | } 39 | 40 | @Override 41 | public boolean equals(Object o) { 42 | if (this == o) return true; 43 | if (!(o instanceof User)) return false; 44 | User user = (User) o; 45 | return Objects.equals(getUsername(), user.getUsername()) && 46 | Objects.equals(getPassword(), user.getPassword()); 47 | } 48 | 49 | @Override 50 | public int hashCode() { 51 | return Objects.hash(getUsername(), getPassword()); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/java/com/epam/ta/page/AbstractPage.java: -------------------------------------------------------------------------------- 1 | package com.epam.ta.page; 2 | 3 | import org.openqa.selenium.WebDriver; 4 | 5 | public abstract class AbstractPage 6 | { 7 | protected WebDriver driver; 8 | 9 | protected abstract AbstractPage openPage(); 10 | protected final int WAIT_TIMEOUT_SECONDS = 10; 11 | 12 | protected AbstractPage(WebDriver driver) 13 | { 14 | this.driver = driver; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/java/com/epam/ta/page/CreateNewRepositoryPage.java: -------------------------------------------------------------------------------- 1 | package com.epam.ta.page; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import org.openqa.selenium.By; 6 | import org.openqa.selenium.WebDriver; 7 | import org.openqa.selenium.WebElement; 8 | import org.openqa.selenium.support.FindBy; 9 | import org.openqa.selenium.support.PageFactory; 10 | import org.openqa.selenium.support.ui.ExpectedConditions; 11 | import org.openqa.selenium.support.ui.WebDriverWait; 12 | 13 | public class CreateNewRepositoryPage extends AbstractPage 14 | { 15 | private final String BASE_URL = "http://www.github.com/new"; 16 | private final Logger logger = LogManager.getRootLogger(); 17 | 18 | @FindBy(id = "repository_name") 19 | private WebElement inputRepositoryName; 20 | 21 | @FindBy(id = "repository_description") 22 | private WebElement inputRepositoryDescription; 23 | 24 | @FindBy(xpath = "//form[@id='new_repository']//button[@type='submit']") 25 | private WebElement buttonCreate; 26 | 27 | private final By labelEmptyRepoSetupOptionLocator = By.xpath("//h3/strong[text()='Quick setup']"); 28 | 29 | @FindBy(xpath = "//a[@data-pjax='#js-repo-pjax-container']") 30 | private WebElement linkCurrentRepository; 31 | 32 | public CreateNewRepositoryPage(WebDriver driver) 33 | { 34 | super(driver); 35 | PageFactory.initElements(this.driver, this); 36 | } 37 | 38 | public boolean isCurrentRepositoryEmpty() 39 | { 40 | WebElement labelEmptyRepoSetupOption = new WebDriverWait(driver, WAIT_TIMEOUT_SECONDS) 41 | .until(ExpectedConditions.presenceOfElementLocated(labelEmptyRepoSetupOptionLocator)); 42 | return labelEmptyRepoSetupOption.isDisplayed(); 43 | } 44 | 45 | public CreateNewRepositoryPage createNewRepository(String repositoryName, String repositoryDescription) 46 | { 47 | inputRepositoryName.sendKeys(repositoryName); 48 | inputRepositoryDescription.sendKeys(repositoryDescription); 49 | buttonCreate.click(); 50 | logger.info("Created repository with name: [" + repositoryName + 51 | "[ and description: [" + repositoryDescription + "]"); 52 | return this; 53 | } 54 | 55 | public String getCurrentRepositoryName() 56 | { 57 | return linkCurrentRepository.getText(); 58 | } 59 | 60 | @Override 61 | public CreateNewRepositoryPage openPage() 62 | { 63 | driver.navigate().to(BASE_URL); 64 | return this; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/java/com/epam/ta/page/LoginPage.java: -------------------------------------------------------------------------------- 1 | package com.epam.ta.page; 2 | 3 | import com.epam.ta.model.User; 4 | import org.apache.logging.log4j.LogManager; 5 | import org.apache.logging.log4j.Logger; 6 | import org.openqa.selenium.WebDriver; 7 | import org.openqa.selenium.WebElement; 8 | import org.openqa.selenium.support.FindBy; 9 | import org.openqa.selenium.support.PageFactory; 10 | 11 | public class LoginPage extends AbstractPage 12 | { 13 | private final Logger logger = LogManager.getRootLogger(); 14 | private final String PAGE_URL = "https://github.com/login"; 15 | 16 | @FindBy(id = "login_field") 17 | private WebElement inputLogin; 18 | 19 | @FindBy(id = "password") 20 | private WebElement inputPassword; 21 | 22 | @FindBy(xpath = "//input[@value='Sign in']") 23 | private WebElement buttonSubmit; 24 | 25 | 26 | 27 | public LoginPage(WebDriver driver) 28 | { 29 | super(driver); 30 | PageFactory.initElements(this.driver, this); 31 | } 32 | 33 | @Override 34 | public LoginPage openPage() 35 | { 36 | driver.navigate().to(PAGE_URL); 37 | logger.info("Login page opened"); 38 | return this; 39 | } 40 | 41 | public MainPage login(User user) 42 | { 43 | inputLogin.sendKeys(user.getUsername()); 44 | inputPassword.sendKeys(user.getPassword()); 45 | buttonSubmit.click(); 46 | logger.info("Login performed"); 47 | return new MainPage(driver); 48 | } 49 | 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/java/com/epam/ta/page/MainPage.java: -------------------------------------------------------------------------------- 1 | package com.epam.ta.page; 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 | import org.openqa.selenium.support.ui.ExpectedConditions; 9 | import org.openqa.selenium.support.ui.WebDriverWait; 10 | 11 | public class MainPage extends AbstractPage 12 | { 13 | private final String BASE_URL = "https://github.com/"; 14 | 15 | @FindBy(xpath = "//summary[contains(@aria-label, 'Create new')]") 16 | private WebElement buttonCreateNew; 17 | 18 | @FindBy(xpath = "//a[contains(text(), 'New repository')]") 19 | private WebElement linkNewRepository; 20 | 21 | private final By linkLoggedInUserLocator = By.xpath("//meta[@name='user-login']"); 22 | 23 | public MainPage(WebDriver driver) 24 | { 25 | super(driver); 26 | PageFactory.initElements(this.driver, this); 27 | } 28 | 29 | public CreateNewRepositoryPage invokeNewRepositoryCreation() 30 | { 31 | buttonCreateNew.click(); 32 | linkNewRepository.click(); 33 | return new CreateNewRepositoryPage(driver); 34 | } 35 | 36 | @Override 37 | public MainPage openPage() 38 | { 39 | driver.navigate().to(BASE_URL); 40 | return this; 41 | } 42 | 43 | public String getLoggedInUserName() 44 | { 45 | WebElement linkLoggedInUser = new WebDriverWait(driver, WAIT_TIMEOUT_SECONDS) 46 | .until(ExpectedConditions.presenceOfElementLocated(linkLoggedInUserLocator)); 47 | return linkLoggedInUser.getAttribute("content"); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/java/com/epam/ta/service/TestDataReader.java: -------------------------------------------------------------------------------- 1 | package com.epam.ta.service; 2 | 3 | import java.util.ResourceBundle; 4 | 5 | public class TestDataReader { 6 | private static ResourceBundle resourceBundle = ResourceBundle.getBundle(System.getProperty("environment")); 7 | 8 | public static String getTestData(String key){ 9 | return resourceBundle.getString(key); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/java/com/epam/ta/service/UserCreator.java: -------------------------------------------------------------------------------- 1 | package com.epam.ta.service; 2 | 3 | import com.epam.ta.model.User; 4 | 5 | public class UserCreator { 6 | 7 | public static final String TESTDATA_USER_NAME = "testdata.user.name"; 8 | public static final String TESTDATA_USER_PASSWORD = "testdata.user.password"; 9 | 10 | public static User withCredentialsFromProperty(){ 11 | return new User(TestDataReader.getTestData(TESTDATA_USER_NAME), 12 | TestDataReader.getTestData(TESTDATA_USER_PASSWORD)); 13 | } 14 | 15 | public static User withEmptyUsername(){ 16 | return new User("", TestDataReader.getTestData(TESTDATA_USER_PASSWORD)); 17 | } 18 | 19 | public static User withEmptyPassword(){ 20 | return new User(TestDataReader.getTestData(TESTDATA_USER_NAME), ""); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/java/com/epam/ta/test/CommonConditions.java: -------------------------------------------------------------------------------- 1 | package com.epam.ta.test; 2 | 3 | import com.epam.ta.driver.DriverSingleton; 4 | import com.epam.ta.util.TestListener; 5 | import org.openqa.selenium.WebDriver; 6 | import org.testng.annotations.AfterMethod; 7 | import org.testng.annotations.BeforeMethod; 8 | import org.testng.annotations.Listeners; 9 | 10 | @Listeners({TestListener.class}) 11 | public class CommonConditions { 12 | 13 | protected WebDriver driver; 14 | 15 | 16 | @BeforeMethod() 17 | public void setUp() 18 | { 19 | driver = DriverSingleton.getDriver(); 20 | } 21 | 22 | @AfterMethod(alwaysRun = true) 23 | public void stopBrowser() 24 | { 25 | DriverSingleton.closeDriver(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/java/com/epam/ta/test/RepositoryManagementTests.java: -------------------------------------------------------------------------------- 1 | package com.epam.ta.test; 2 | 3 | import com.epam.ta.model.User; 4 | import com.epam.ta.page.LoginPage; 5 | import com.epam.ta.service.UserCreator; 6 | import com.epam.ta.util.StringUtils; 7 | import org.testng.Assert; 8 | import org.testng.annotations.Test; 9 | 10 | import static org.hamcrest.MatcherAssert.assertThat; 11 | import static org.hamcrest.Matchers.equalTo; 12 | import static org.hamcrest.Matchers.is; 13 | 14 | 15 | public class RepositoryManagementTests extends CommonConditions { 16 | protected static final int REPOSITORY_NAME_POSTFIX_LENGTH = 6; 17 | protected static final String REPOSITORY_DESCRIPTION = "auto-generated test repo"; 18 | 19 | @Test(description = "JIRA-7566") 20 | public void oneCanCreateProject() 21 | { 22 | User testUser = UserCreator.withCredentialsFromProperty(); 23 | String expectedRepositoryName = StringUtils.generateRandomRepositoryNameWithPostfixLength(REPOSITORY_NAME_POSTFIX_LENGTH); 24 | String createdRepositoryName = new LoginPage(driver) 25 | .openPage() 26 | .login(testUser) 27 | .invokeNewRepositoryCreation() 28 | .createNewRepository(expectedRepositoryName, REPOSITORY_DESCRIPTION) 29 | .getCurrentRepositoryName(); 30 | 31 | assertThat(createdRepositoryName, is(equalTo(expectedRepositoryName))); 32 | } 33 | 34 | @Test(description = "JIRA-7567") 35 | public void newProjectsAreEmpty() 36 | { 37 | User testUser = UserCreator.withCredentialsFromProperty(); 38 | String testRepositoryName = StringUtils.generateRandomRepositoryNameWithPostfixLength(REPOSITORY_NAME_POSTFIX_LENGTH); 39 | boolean isCurrentRepositoryEmpty = new LoginPage(driver) 40 | .openPage() 41 | .login(testUser) 42 | .invokeNewRepositoryCreation() 43 | .createNewRepository(testRepositoryName, REPOSITORY_DESCRIPTION) 44 | .isCurrentRepositoryEmpty(); 45 | 46 | Assert.assertTrue(isCurrentRepositoryEmpty, "newly created repository is not empty"); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/java/com/epam/ta/test/UserAccessTests.java: -------------------------------------------------------------------------------- 1 | package com.epam.ta.test; 2 | 3 | import com.epam.ta.model.User; 4 | import com.epam.ta.page.LoginPage; 5 | import com.epam.ta.service.UserCreator; 6 | import org.testng.annotations.Test; 7 | 8 | import static org.hamcrest.MatcherAssert.assertThat; 9 | import static org.hamcrest.Matchers.equalTo; 10 | import static org.hamcrest.Matchers.is; 11 | 12 | 13 | public class UserAccessTests extends CommonConditions { 14 | @Test 15 | public void oneCanLoginGithub() 16 | { 17 | User testUser = UserCreator.withCredentialsFromProperty(); 18 | String loggedInUserName = new LoginPage(driver) 19 | .openPage() 20 | .login(testUser) 21 | .getLoggedInUserName(); 22 | assertThat(loggedInUserName, is(equalTo(testUser.getUsername()))); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/java/com/epam/ta/util/StringUtils.java: -------------------------------------------------------------------------------- 1 | package com.epam.ta.util; 2 | 3 | import java.util.Random; 4 | 5 | public class StringUtils 6 | { 7 | private static final String ALFANUMERICAL_ALL_CAPS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 8 | private static Random random = new Random(); 9 | 10 | public static String getRandomString(int stringLength) 11 | { 12 | StringBuilder stringBuilder = new StringBuilder(stringLength); 13 | for (int i = 0; i < stringLength; i++) 14 | { 15 | stringBuilder.append(ALFANUMERICAL_ALL_CAPS.charAt(random.nextInt(ALFANUMERICAL_ALL_CAPS.length()))); 16 | } 17 | return stringBuilder.toString(); 18 | } 19 | 20 | public static String generateRandomRepositoryNameWithPostfixLength(int postfixLength){ 21 | return "testRepo_".concat(getRandomString(postfixLength)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/java/com/epam/ta/util/TestListener.java: -------------------------------------------------------------------------------- 1 | package com.epam.ta.util; 2 | 3 | import com.epam.ta.driver.DriverSingleton; 4 | import org.apache.commons.io.FileUtils; 5 | import org.apache.logging.log4j.LogManager; 6 | import org.apache.logging.log4j.Logger; 7 | import org.openqa.selenium.OutputType; 8 | import org.openqa.selenium.TakesScreenshot; 9 | import org.testng.ITestContext; 10 | import org.testng.ITestListener; 11 | import org.testng.ITestResult; 12 | 13 | import java.io.File; 14 | import java.io.IOException; 15 | import java.time.ZonedDateTime; 16 | import java.time.format.DateTimeFormatter; 17 | 18 | 19 | public class TestListener implements ITestListener { 20 | private Logger log = LogManager.getRootLogger(); 21 | 22 | public void onTestStart(ITestResult iTestResult) { 23 | 24 | } 25 | 26 | public void onTestSuccess(ITestResult iTestResult) { 27 | 28 | } 29 | 30 | public void onTestFailure(ITestResult iTestResult) { 31 | saveScreenshot(); 32 | } 33 | 34 | public void onTestSkipped(ITestResult iTestResult) { 35 | 36 | } 37 | 38 | public void onTestFailedButWithinSuccessPercentage(ITestResult iTestResult) { 39 | 40 | } 41 | 42 | public void onStart(ITestContext iTestContext) { 43 | 44 | } 45 | 46 | public void onFinish(ITestContext iTestContext) { 47 | 48 | } 49 | 50 | private void saveScreenshot(){ 51 | File screenCapture = ((TakesScreenshot)DriverSingleton 52 | .getDriver()) 53 | .getScreenshotAs(OutputType.FILE); 54 | try { 55 | FileUtils.copyFile(screenCapture, new File( 56 | ".//target/screenshots/" 57 | + getCurrentTimeAsString() + 58 | ".png")); 59 | } catch (IOException e) { 60 | log.error("Failed to save screenshot: " + e.getLocalizedMessage()); 61 | } 62 | } 63 | 64 | private String getCurrentTimeAsString(){ 65 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "uuuu-MM-dd_HH-mm-ss" ); 66 | return ZonedDateTime.now().format(formatter); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/resources/dev.properties: -------------------------------------------------------------------------------- 1 | testdata.user.name=test-automation-user 2 | testdata.user.password=Time4Death! 3 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d %p %c{2} [%t] %l %m%n 7 | 8 | 9 | 10 | 11 | %d %p %c{2} [%t] %m%n 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/resources/qa.properties: -------------------------------------------------------------------------------- 1 | testdata.user.name=test-automation-user 2 | testdata.user.password=wrong_password 3 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/resources/staging.properties: -------------------------------------------------------------------------------- 1 | testdata.user.name=test-automation-user 2 | testdata.user.password=Time4Death! 3 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/resources/testng-all.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /java/GitHubAutomation/src/test/resources/testng-smoke.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | --------------------------------------------------------------------------------