diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..903672f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,96 @@ +name: Java CI with Maven + +on: + pull_request: + branches: + - main + push: + branches: + - main + +jobs: + build: + name: 'Run tests' + runs-on: ubuntu-latest + + steps: + # 1. Cloning + - name: Git clone + uses: actions/checkout@v4 + + # 2. Install Java 21 + - name: Setup JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'corretto' + cache: 'maven' + + # 3. Run tests (not stop workflow if failure ) + - name: Build and run tests with Maven + run: mvn -B -e clean test -Dselenium.headless=true || true + env: + CHROME_OPTIONS: --remote-allow-origins=*;--disable-gpu;--no-sandbox;--disable-dev-shm-usage;--headless=new;--window-size=1920,1080 + + # 4. Output failed tests + - name: Print failed tests + if: failure() + run: | + echo "---- TEST FAILURES ----" + cat target/surefire-reports/*.txt || true + + # 5. Attach screenshots + - name: Attach screenshots + if: always() + uses: actions/upload-artifact@v4 + with: + name: screenshots + path: ${{ github.workspace }}/screenshots + + # 6. Get Allure (gh-pages) + - name: Get Allure history + uses: actions/checkout@v4 + if: always() + continue-on-error: true + with: + ref: gh-pages + path: gh-pages + + # 7. Build Allure report + - name: Build Allure report + uses: simple-elf/allure-report-action@master + if: always() + id: allure-report + with: + allure_results: target/allure-results + gh_pages: gh-pages + allure_report: allure-report + allure_history: allure-history + + # 8. Upload Allure report artifact + - name: Upload Allure report artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: allure-report + path: target/allure-report + + # 9. Check allure-results + - name: Check Allure results + run: ls -la target/allure-results + + # 10. Publish Allure to GitHub Pages + - name: Publish Allure report to Github Pages + if: always() + uses: peaceiris/actions-gh-pages@v2 + env: + PERSONAL_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PUBLISH_BRANCH: gh-pages + PUBLISH_DIR: allure-history + + - name: Upload Allure HTML report as artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: allure-report + path: allure-report diff --git a/src/test/java/ui/testing/base/BasePage.java b/src/test/java/ui/testing/base/BasePage.java index fab884b..619b9ef 100644 --- a/src/test/java/ui/testing/base/BasePage.java +++ b/src/test/java/ui/testing/base/BasePage.java @@ -6,7 +6,7 @@ import java.time.Duration; -public class BasePage { +public abstract class BasePage> { private final WebDriver driver; public BasePage(WebDriver driver) { diff --git a/src/test/java/ui/testing/base/BaseTest.java b/src/test/java/ui/testing/base/BaseTest.java index d5aa13a..2423099 100644 --- a/src/test/java/ui/testing/base/BaseTest.java +++ b/src/test/java/ui/testing/base/BaseTest.java @@ -1,5 +1,6 @@ package ui.testing.base; +import io.github.bonigarcia.wdm.WebDriverManager; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; @@ -16,8 +17,19 @@ public SoftAssert softAssert() { @BeforeMethod public void setUp() { + WebDriverManager.chromedriver().setup(); ChromeOptions chromeOptions = new ChromeOptions(); + chromeOptions.addArguments("--headless"); // стабильно на Windows chromeOptions.addArguments("--window-size=1920,1080"); + chromeOptions.addArguments("--disable-gpu"); + chromeOptions.addArguments("--remote-allow-origins=*"); + + if (!System.getProperty("os.name").toLowerCase().contains("win")) { + chromeOptions.addArguments("--no-sandbox", "--disable-dev-shm-usage"); + chromeOptions.addArguments("--user-data-dir=/tmp/chrome-profile-" + System.currentTimeMillis()); + } else { + chromeOptions.addArguments("--user-data-dir=" + System.getProperty("java.io.tmpdir") + "chrome-profile-" + System.currentTimeMillis()); + } driver = new ChromeDriver(chromeOptions); driver.get("http://uitestingplayground.com/"); } diff --git a/src/test/java/ui/testing/page/AjaxDataPage.java b/src/test/java/ui/testing/page/AjaxDataPage.java new file mode 100644 index 0000000..da6fc3c --- /dev/null +++ b/src/test/java/ui/testing/page/AjaxDataPage.java @@ -0,0 +1,34 @@ +package ui.testing.page; + +import io.qameta.allure.Step; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; +import ui.testing.base.BasePage; + +import java.time.Duration; + +public class AjaxDataPage extends BasePage +{ + public AjaxDataPage(WebDriver driver) { + super(driver); + } + @Step("Press the button : {text}") + public AjaxDataPage pressButtonAjaxRequest() { + WebElement btn = getDriver().findElement(By.id("ajaxButton")); + btn.click(); + String text = btn.getText(); + return this; + } + @Step("Waiting until appear loaded label : {text}") + public String waitUntilLoadedLabel() { + WebElement result = new WebDriverWait(getDriver(), Duration.ofSeconds(30)).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//div[@id='content']/p"))); + String text = result.getText(); + + return text; + } + + +} diff --git a/src/test/java/ui/testing/page/ClassAttributePage.java b/src/test/java/ui/testing/page/ClassAttributePage.java index 983cb9c..b83c7fb 100644 --- a/src/test/java/ui/testing/page/ClassAttributePage.java +++ b/src/test/java/ui/testing/page/ClassAttributePage.java @@ -7,7 +7,7 @@ import org.openqa.selenium.support.ui.ExpectedConditions; import ui.testing.base.BasePage; -public class ClassAttributePage extends BasePage { +public class ClassAttributePage extends BasePage { public ClassAttributePage(WebDriver driver) { super(driver); } diff --git a/src/test/java/ui/testing/page/DynamicIdPage.java b/src/test/java/ui/testing/page/DynamicIdPage.java index e5c02a6..683f7f4 100644 --- a/src/test/java/ui/testing/page/DynamicIdPage.java +++ b/src/test/java/ui/testing/page/DynamicIdPage.java @@ -5,7 +5,7 @@ import org.openqa.selenium.WebElement; import ui.testing.base.BasePage; -public class DynamicIdPage extends BasePage { +public class DynamicIdPage extends BasePage { public DynamicIdPage(WebDriver driver) { super(driver); } diff --git a/src/test/java/ui/testing/page/HiddenLayersPage.java b/src/test/java/ui/testing/page/HiddenLayersPage.java index 53331ba..f76028d 100644 --- a/src/test/java/ui/testing/page/HiddenLayersPage.java +++ b/src/test/java/ui/testing/page/HiddenLayersPage.java @@ -7,7 +7,7 @@ import org.openqa.selenium.support.ui.ExpectedConditions; import ui.testing.base.BasePage; -public class HiddenLayersPage extends BasePage { +public class HiddenLayersPage extends BasePage { public HiddenLayersPage(WebDriver driver) { super(driver); } diff --git a/src/test/java/ui/testing/page/HomePage.java b/src/test/java/ui/testing/page/HomePage.java index 44a5e83..c5acd79 100644 --- a/src/test/java/ui/testing/page/HomePage.java +++ b/src/test/java/ui/testing/page/HomePage.java @@ -8,7 +8,7 @@ import org.testng.Reporter; import ui.testing.base.BasePage; -public class HomePage extends BasePage { +public class HomePage extends BasePage { public HomePage(WebDriver driver) { super(driver); } diff --git a/src/test/java/ui/testing/page/LoadDelayPage.java b/src/test/java/ui/testing/page/LoadDelayPage.java index 5e1c010..5a88e95 100644 --- a/src/test/java/ui/testing/page/LoadDelayPage.java +++ b/src/test/java/ui/testing/page/LoadDelayPage.java @@ -7,7 +7,7 @@ import org.openqa.selenium.support.ui.ExpectedConditions; import ui.testing.base.BasePage; -public class LoadDelayPage extends BasePage { +public class LoadDelayPage extends BasePage { public LoadDelayPage(WebDriver driver) { super(driver); } diff --git a/src/test/java/ui/testing/test/FirstRowTest.java b/src/test/java/ui/testing/test/FirstRowTest.java index ccbfa78..4002abc 100644 --- a/src/test/java/ui/testing/test/FirstRowTest.java +++ b/src/test/java/ui/testing/test/FirstRowTest.java @@ -34,7 +34,7 @@ public void testDynamicId() { Assert.assertNotEquals(id, idNew, "ID должен меняться после обновления страницы"); } - @Test(description = "Class Attribute - Verify that class-based XPath is well formed") + @Test @Story("Class Attribute") @Severity(SeverityLevel.MINOR) public void testClassAttribute() { @@ -53,7 +53,7 @@ public void testClassAttribute() { softAssert().assertAll(); } - @Test(description = "Hidden Layers - Ensure test doesn't click invisible elements") + @Test @Story("Hidden Layers") @Severity(SeverityLevel.CRITICAL) public void testHiddenLayers() { @@ -73,7 +73,7 @@ public void testHiddenLayers() { softAssert().assertAll(); } - @Test(description = "Load Delay - Ensure that a test is capable of waiting for a page to load") + @Test() @Story("Load Delay") @Severity(SeverityLevel.CRITICAL) public void testLoadDelay() { @@ -85,4 +85,5 @@ public void testLoadDelay() { Allure.addAttachment("Button is shown : ", delay); }); } + } diff --git a/src/test/java/ui/testing/test/SecondRowTest.java b/src/test/java/ui/testing/test/SecondRowTest.java new file mode 100644 index 0000000..f34fed1 --- /dev/null +++ b/src/test/java/ui/testing/test/SecondRowTest.java @@ -0,0 +1,33 @@ +package ui.testing.test; + +import io.qameta.allure.*; +import org.openqa.selenium.WebDriver; +import org.testng.annotations.Listeners; +import org.testng.annotations.Test; +import ui.testing.base.BasePage; +import ui.testing.base.BaseTest; +import ui.testing.page.AjaxDataPage; +import ui.testing.page.HomePage; +import ui.testing.page.LoadDelayPage; + +@Listeners(ui.testing.utils.TestListener.class) +@Epic("UI Testing Playground") +@Feature("Elements") +@Owner("RomanB") +public class SecondRowTest extends BaseTest { + + @Test + @Story("AJAX Data") + @Severity(SeverityLevel.CRITICAL) + public void testAjaxData() { + Allure.step("Go to AjaxDataPage and wait for all element loaded", ()-> { + String ajax = new HomePage(driver) + .goToPage("AJAX Data", new AjaxDataPage(driver)) + .pressButtonAjaxRequest() + .waitUntilLoadedLabel(); + + softAssert().assertEquals(ajax, "Data loaded with AJAX get request."); + Allure.addAttachment("Label is loaded : ", ajax); + }); + } +} diff --git a/src/test/resources/suites/suiteRow1.xml b/src/test/resources/suites/suiteRow1.xml deleted file mode 100644 index e69de29..0000000