diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..72fbc0a --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,50 @@ +name: Run tests +env: + ALLURE_VERSION: "2.10.0" + +on: + push: + branches: + - main + + pull_request: + branches: + - main + release: + types: + - created + +jobs: + build: + name: Tests on JDK + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + java: [ 11, 17 ] + + steps: + - uses: actions/checkout@v3 + - name: Set up JDK ${{ matrix.java }} + uses: actions/setup-java@v3 + with: + java-version: ${{ matrix.java }} + java-package: jdk + distribution: 'temurin' + cache: 'maven' + + - name: Build with Maven + id: build + run: mvn clean install -DskipTests -ntp + + - name: Tests + id: functests + timeout-minutes: 10 + continue-on-error: true + run: mvn test -ntp + + - name: Check tests are passed + if: ${{ steps.functests.outcome != 'success' }} + run: | + echo Tests result: ${{ steps.functests.outcome }} + exit 1 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 524f096..45d878c 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,12 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* replay_pid* + +# Idea files +*.iml +.idea/ +target/ + +# Allure files +.allure/ +allure-results/ \ No newline at end of file diff --git a/README.md b/README.md index 22ec999..592c457 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,27 @@ -# jdn-template-selenide -Template project for JDN with Selenide +# Selenide Testng empty template + +Empty template for Test Automation project with Selenide + +# Instruction: + +1. Download template and unpack in appropriate folder + +2. Open project in IDE (for example IntelliJIdea) + +3. Reporting: Allure is enabled, after running tests just run **allure:serve** in maven plugins (allure should be + installed locally) + +4. Parameters that can be changed placed in src/test/java/test/BaseTest.java + +- baseUrl - base url of your site under tests +- browser - chrome/edge/firefox etc. +- pageLoadTimeout - timeout to wait page load +- headless - to run tests in headless mode, so if you want to hide browser set true + +5. TestNg Retry and before after listeners: You can also modify rules of retry tests (now it is 1 retry for each test) + and actions before/after all tests (now it prints test name and result) in **testng** folder + +6. pages generated by JDN should be places in src/main/java/pages package + +7. Each page object class must be inherited from BasePage, including one of the mandatory paremeters is PATH describing + the URI of the page e.g. in http://example.com/login PATH = "/login". diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..16cc0c4 --- /dev/null +++ b/pom.xml @@ -0,0 +1,130 @@ + + + 4.0.0 + + com.epam.jdi + jdn-template-selenide + 1.0.0 + Template: Selenide TestNG Testing project + + + 7.8.0 + 2.7 + 2.22.0 + 6.19.1 + 1.18.22 + 2.13.6 + 2.12.0 + 3.8.1 + 2.22.2 + 11 + 11 + + https://example.com + true + chrome + + + + + + org.apache.commons + commons-configuration2 + ${commons.config.version} + + + + org.apache.logging.log4j + log4j-core + ${log4j.core.version} + + + + com.codeborne + selenide + ${selenide.version} + + + + org.testng + testng + ${testng.version} + test + + + + org.projectlombok + lombok + ${lombok.version} + test + + + + io.qameta.allure + allure-testng + ${allure.version} + + + io.qameta.allure + allure-selenide + ${allure.version} + + + + + + + io.qameta.allure + allure-maven + ${allure.maven.version} + + ${allure.version} + + + allure.results.directory + target + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.compiler.plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven.surefire.plugin.version} + + + ${project.build.directory}/allure-results + + + src/test/resources/testng.xml + + + + listener + io.qameta.allure.testng.AllureTestNg + + + + + + + + src/test/resources + + + src/test/resources + true + + + + diff --git a/src/main/java/pages/BasePage.java b/src/main/java/pages/BasePage.java new file mode 100644 index 0000000..33e120e --- /dev/null +++ b/src/main/java/pages/BasePage.java @@ -0,0 +1,18 @@ +package pages; + +import com.codeborne.selenide.Selenide; + +public abstract class BasePage { + + protected String path; + protected String title; + + protected BasePage(final String title, final String path) { + this.path = path; + this.title = title; + } + + public void openPage() { + Selenide.open(this.path); + } +} diff --git a/src/main/java/pages/HomePage.java b/src/main/java/pages/HomePage.java new file mode 100644 index 0000000..fae09ea --- /dev/null +++ b/src/main/java/pages/HomePage.java @@ -0,0 +1,15 @@ +package pages; + +import com.codeborne.selenide.SelenideElement; + +import static com.codeborne.selenide.Selenide.$; + +public class HomePage extends BasePage { + private static final String PATH = "/"; + private static final String TITLE = "/"; + public SelenideElement moreInformationLink = $("p > a").as("more information link"); + + public HomePage() { + super(TITLE, PATH); + } +} diff --git a/src/test/java/test/BaseTest.java b/src/test/java/test/BaseTest.java new file mode 100644 index 0000000..deacc13 --- /dev/null +++ b/src/test/java/test/BaseTest.java @@ -0,0 +1,40 @@ +package test; + +import com.codeborne.selenide.Configuration; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.logevents.SelenideLogger; +import io.qameta.allure.selenide.AllureSelenide; +import org.testng.annotations.AfterSuite; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Listeners; + +import static com.codeborne.selenide.FileDownloadMode.FOLDER; +import static java.lang.Boolean.parseBoolean; +import static java.lang.System.getProperty; + +@Listeners() +public interface BaseTest { + String baseUrl = getProperty("base.url", "https://example.com"); + String browser = getProperty("browser", "chrome"); + boolean headless = parseBoolean(getProperty("headless", "true")); + + @BeforeSuite + public static void setUp() { + SelenideLogger.addListener("AllureSelenide", new AllureSelenide().screenshots(true) + .savePageSource(false)); + Configuration.baseUrl = baseUrl; + Configuration.browser = browser; // You can also use "firefox", "edge", etc. + Configuration.pageLoadTimeout = 20000; + Configuration.headless = headless; + Configuration.browserSize = "1920x1200"; + Configuration.screenshots = true; + Configuration.fileDownload = FOLDER; + } + + @AfterSuite + + public static void tearDown() { + SelenideLogger.removeListener("AllureSelenide"); + Selenide.closeWebDriver(); + } +} diff --git a/src/test/java/test/ExampleTests.java b/src/test/java/test/ExampleTests.java new file mode 100644 index 0000000..b224c8a --- /dev/null +++ b/src/test/java/test/ExampleTests.java @@ -0,0 +1,14 @@ +package test; + +import org.testng.annotations.Test; +import pages.HomePage; + +public class ExampleTests implements BaseTest { + HomePage homePage = new HomePage(); + + @Test(description = "Example test") + public void openPageTest() { + homePage.openPage(); + homePage.moreInformationLink.click(); + } +} \ No newline at end of file diff --git a/src/test/java/testng/RetryAnalyzer.java b/src/test/java/testng/RetryAnalyzer.java new file mode 100644 index 0000000..494a042 --- /dev/null +++ b/src/test/java/testng/RetryAnalyzer.java @@ -0,0 +1,19 @@ +package testng; + +import org.testng.IRetryAnalyzer; +import org.testng.ITestResult; + +public class RetryAnalyzer implements IRetryAnalyzer { + + private int retryCount = 0; + private static final int MAX_RETRY_COUNT = 3; + + @Override + public boolean retry(ITestResult iTestResult) { + if (retryCount < MAX_RETRY_COUNT) { + retryCount++; + return true; // Retry the test + } + return false; // No retry + } +} diff --git a/src/test/java/testng/RetryTransformer.java b/src/test/java/testng/RetryTransformer.java new file mode 100644 index 0000000..a0efd14 --- /dev/null +++ b/src/test/java/testng/RetryTransformer.java @@ -0,0 +1,15 @@ +package testng; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +import org.testng.IAnnotationTransformer; +import org.testng.annotations.ITestAnnotation; + +public class RetryTransformer implements IAnnotationTransformer { + + @Override + public void transform(ITestAnnotation iTestAnnotation, Class aClass, Constructor constructor, Method method) { + iTestAnnotation.setRetryAnalyzer(RetryAnalyzer.class); + } +} diff --git a/src/test/resources/log4j2.xml b/src/test/resources/log4j2.xml new file mode 100644 index 0000000..fb1a146 --- /dev/null +++ b/src/test/resources/log4j2.xml @@ -0,0 +1,60 @@ + + + + + jdiEvents + ./target/.logs + + + + + + + + + ${baseDir}/${logFileName}_%d{yyyy-MM-dd__HH-mm}_%i.log + + %d{HH:mm:ss} [%t] %-5level %logger{6} - %msg%n + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/testng.xml b/src/test/resources/testng.xml new file mode 100644 index 0000000..9a7007d --- /dev/null +++ b/src/test/resources/testng.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file