mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
test java playwright test
This commit is contained in:
parent
dee23c6069
commit
f58276b655
2
e2e-tests/.gitignore
vendored
2
e2e-tests/.gitignore
vendored
@ -3,4 +3,4 @@ cypress/screenshots/
|
||||
cypress/videos/
|
||||
cypress/reports/
|
||||
cucumber-messages.ndjson
|
||||
|
||||
**/target
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
###############################################################################
|
||||
# Dockerfile to create a ready-to-use Playwright Docker image for end-to-end
|
||||
# testing.
|
||||
#
|
||||
# To avoid hardcoded versoning of Playwright, this Dockerfile is a custom
|
||||
# version of the ready-to-use Dockerfile privided by Playwright developement
|
||||
# (https://github.com/microsoft/playwright/blob/main/utils/docker/Dockerfile.focal)
|
||||
#
|
||||
# Here the latest stable versions of the browsers Chromium, Firefox, and Webkit
|
||||
# (Safari) are installed, icluding all dependencies based on Ubuntu specified by
|
||||
# Playwright developement.
|
||||
###############################################################################
|
||||
|
||||
FROM ubuntu:focal
|
||||
|
||||
# set a timezone for the Playwright browser dependency installation
|
||||
ARG TZ=Europe/Berlin
|
||||
|
||||
ARG DOCKER_WORKDIR=/tests/
|
||||
WORKDIR $DOCKER_WORKDIR
|
||||
|
||||
# package manager preparation
|
||||
RUN apt-get -qq update && apt-get install -qq -y curl gpg > /dev/null
|
||||
# for Node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash -
|
||||
# for Yarn
|
||||
RUN curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
|
||||
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
|
||||
|
||||
# install node v16 and Yarn
|
||||
RUN apt-get -qq update && apt-get install -qq -y nodejs yarn
|
||||
|
||||
COPY tests/package.json tests/yarn.lock $DOCKER_WORKDIR
|
||||
|
||||
# install Playwright with all dependencies
|
||||
# for the browsers chromium, firefox, and webkit
|
||||
RUN yarn install && yarn playwright install --with-deps
|
||||
|
||||
# clean up
|
||||
RUN rm -rf /var/lib/apt/lists/* && apt-get -qq clean
|
||||
|
||||
COPY tests/ $DOCKER_WORKDIR
|
||||
@ -1,24 +0,0 @@
|
||||
# Gradido End-to-End Testing with [Playwright](https://playwright.dev/) (CI-ready via Docker)
|
||||
|
||||
|
||||
A sample setup to show-case Playwright (using Typescript) as an end-to-end testing tool for Gradido runniing in a Docker container.
|
||||
Here we have a simple UI-based happy path login test running against the DEV system.
|
||||
|
||||
## Precondition
|
||||
Since dependencies and configurations for Github Actions integration is not set up yet, please run in root directory
|
||||
|
||||
```bash
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
to boot up the DEV system, before running the test.
|
||||
|
||||
## Execute the test
|
||||
|
||||
```bash
|
||||
# build a Docker image from the Dockerfile
|
||||
docker build -t gradido_e2e-tests-playwright .
|
||||
|
||||
# run the Docker container and execute the given tests
|
||||
docker run -it --network=host gradido_e2e-tests-playwright yarn playwright-e2e-tests
|
||||
```
|
||||
12
e2e-tests/playwright/java/Readme.md
Normal file
12
e2e-tests/playwright/java/Readme.md
Normal file
@ -0,0 +1,12 @@
|
||||
# gradido-e2e-tests-playwright with java
|
||||
|
||||
Experimental End-to-end tests with Playwright and Java
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Java 17
|
||||
- Maven
|
||||
- Playwright
|
||||
- Gradle
|
||||
- Git
|
||||
|
||||
52
e2e-tests/playwright/java/pom.xml
Normal file
52
e2e-tests/playwright/java/pom.xml
Normal file
@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>net.gradido</groupId>
|
||||
<artifactId>gradido-e2e-tests-playwright</artifactId>
|
||||
<version>0.0.1</version>
|
||||
<name>Gradido Playwright End-to-End Tests in Java</name>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.playwright</groupId>
|
||||
<artifactId>playwright</artifactId>
|
||||
<version>1.52.0</version>
|
||||
</dependency>
|
||||
<!-- JUnit Jupiter API & Engine -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>5.10.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.10.1</version>
|
||||
<!-- References to interface static methods are allowed only at source level 1.8 or above -->
|
||||
<configuration>
|
||||
<source>17</source>
|
||||
<target>17</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M9</version>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test*.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@ -0,0 +1,68 @@
|
||||
package net.gradido.e2e.base;
|
||||
|
||||
import com.microsoft.playwright.Browser;
|
||||
import com.microsoft.playwright.BrowserContext;
|
||||
import com.microsoft.playwright.Playwright;
|
||||
import com.microsoft.playwright.Page;
|
||||
import com.microsoft.playwright.Tracing;
|
||||
import org.junit.jupiter.api.*;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
// Subclasses will inherit PER_CLASS behavior.
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
public class BaseTest {
|
||||
protected Playwright playwright;
|
||||
protected Browser browser;
|
||||
|
||||
@BeforeAll
|
||||
void setUpAll() {
|
||||
playwright = Playwright.create();
|
||||
browser = playwright.chromium().launch();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
void tearDownAll() {
|
||||
playwright.close();
|
||||
}
|
||||
|
||||
// New instance for each test method.
|
||||
protected BrowserContext context;
|
||||
protected Page page;
|
||||
protected Path currentTracePath;
|
||||
|
||||
@BeforeEach
|
||||
void setUp(TestInfo testInfo) {
|
||||
context = browser.newContext(
|
||||
new Browser.NewContextOptions().setBaseURL("http://localhost:3000")
|
||||
);
|
||||
context.route("**/*", route -> {
|
||||
String url = route.request().url();
|
||||
|
||||
// we skip fontawesome and googleapis requests, we don't need them for functions test, but they cost time
|
||||
if (url.contains("use.fontawesome.com") || url.contains("fonts.googleapis.com")) {
|
||||
route.abort();
|
||||
return;
|
||||
}
|
||||
route.resume();
|
||||
});
|
||||
|
||||
// Start tracing before creating
|
||||
String testName = testInfo.getDisplayName().replaceAll("[^a-zA-Z0-9]", "");
|
||||
currentTracePath = Paths.get("target/traces/" + testName + ".zip");
|
||||
context.tracing().start(new Tracing.StartOptions()
|
||||
.setScreenshots(true)
|
||||
.setSnapshots(true)
|
||||
.setSources(true));
|
||||
page = context.newPage();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
// Stop tracing and export it into a zip archive.
|
||||
context.tracing().stop(new Tracing.StopOptions().setPath(currentTracePath));
|
||||
|
||||
page.close();
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package net.gradido.e2e.components;
|
||||
|
||||
import com.microsoft.playwright.Locator;
|
||||
import com.microsoft.playwright.Page;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class Toasts {
|
||||
private final Page page;
|
||||
|
||||
public final Locator toastSlot;
|
||||
public final Locator toastTypeError;
|
||||
public final Locator toastTitle;
|
||||
public final Locator toastMessage;
|
||||
|
||||
public Toasts(Page page) {
|
||||
this.page = page;
|
||||
toastSlot = page.locator("#__BVID__toaster-container");
|
||||
toastTypeError = toastSlot.locator(".toast.text-bg-danger");
|
||||
toastTitle = toastTypeError.locator(".gdd-toaster-title");
|
||||
toastMessage = toastTypeError.locator(".gdd-toaster-body");
|
||||
}
|
||||
|
||||
public void assertErrorToastVisible() {
|
||||
toastTypeError.waitFor(); // auf Fehler-Toast warten
|
||||
assertTrue(toastTitle.isVisible());
|
||||
assertTrue(toastMessage.isVisible());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package net.gradido.e2e.pages;
|
||||
|
||||
import com.microsoft.playwright.Locator;
|
||||
import com.microsoft.playwright.Page;
|
||||
import com.microsoft.playwright.Response;
|
||||
|
||||
public class LoginPage {
|
||||
private final Page page;
|
||||
|
||||
private final Locator emailInput;
|
||||
private final Locator passwordInput;
|
||||
private final Locator submitButton;
|
||||
|
||||
public LoginPage(Page page) {
|
||||
this.page = page;
|
||||
emailInput = page.locator("input[name='email']");
|
||||
passwordInput = page.locator("input[name='password']");
|
||||
submitButton = page.locator("button[type='submit']");
|
||||
}
|
||||
|
||||
public void login(String email, String password) {
|
||||
emailInput.fill(email);
|
||||
passwordInput.fill(password);
|
||||
Response response = page.waitForResponse("**/graphql", () -> {
|
||||
submitButton.click();
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package net.gradido.e2e.tests;
|
||||
|
||||
import net.gradido.e2e.base.BaseTest;
|
||||
import net.gradido.e2e.pages.LoginPage;
|
||||
import net.gradido.e2e.components.Toasts;
|
||||
import org.junit.jupiter.api.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class InvalidLoginTest extends BaseTest {
|
||||
private LoginPage loginPage;
|
||||
|
||||
@BeforeEach
|
||||
void initPageObjects() {
|
||||
loginPage = new LoginPage(page);
|
||||
}
|
||||
|
||||
@Test
|
||||
void invalidUserSeesError() {
|
||||
page.navigate("http://localhost:3000/login");
|
||||
loginPage.login("peter@lustig.de", "wrongpass");
|
||||
Toasts toast = new Toasts(page);
|
||||
toast.assertErrorToastVisible();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package net.gradido.e2e.tests;
|
||||
|
||||
import net.gradido.e2e.base.BaseTest;
|
||||
import net.gradido.e2e.pages.LoginPage;
|
||||
import net.gradido.e2e.components.Toasts;
|
||||
|
||||
import org.junit.jupiter.api.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class ValidLoginTest extends BaseTest {
|
||||
private LoginPage loginPage;
|
||||
|
||||
@BeforeEach
|
||||
void initPageObjects() {
|
||||
loginPage = new LoginPage(page);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validUserCanLogin() {
|
||||
page.navigate("http://localhost:3000/login");
|
||||
loginPage.login("peter@lustig.de", "Aa12345_");
|
||||
page.waitForURL("http://localhost:3000/overview");
|
||||
assertTrue(page.url().contains("/overview"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
junit.jupiter.execution.parallel.enabled = true
|
||||
junit.jupiter.execution.parallel.mode.default = same_thread
|
||||
junit.jupiter.execution.parallel.mode.classes.default = concurrent
|
||||
junit.jupiter.execution.parallel.config.strategy=dynamic
|
||||
junit.jupiter.execution.parallel.config.dynamic.factor=0.5
|
||||
@ -1,10 +0,0 @@
|
||||
import { FullConfig } from '@playwright/test';
|
||||
|
||||
async function globalSetup(config: FullConfig) {
|
||||
process.env.EMAIL = 'bibi@bloxberg.de';
|
||||
process.env.PASSWORD = 'Aa12345_';
|
||||
process.env.GMS_ACTIVE = false;
|
||||
process.env.HUMHUB_ACTIVE = false;
|
||||
}
|
||||
|
||||
export default globalSetup;
|
||||
@ -1,15 +0,0 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from './models/login_page';
|
||||
import { WelcomePage } from './models/welcome_page';
|
||||
|
||||
|
||||
test('Gradido login test (happy path)', async ({ page }) => {
|
||||
const { EMAIL, PASSWORD } = process.env;
|
||||
const loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.enterEmail(EMAIL);
|
||||
await loginPage.enterPassword(PASSWORD);
|
||||
await loginPage.submitLogin();
|
||||
// assertions
|
||||
await expect(page).toHaveURL('./overview');
|
||||
});
|
||||
@ -1,33 +0,0 @@
|
||||
import { expect, test, Locator, Page } from '@playwright/test';
|
||||
|
||||
export class LoginPage {
|
||||
readonly page: Page;
|
||||
readonly url: string;
|
||||
readonly emailInput: Locator;
|
||||
readonly passwordInput: Locator;
|
||||
readonly submitBtn: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.url = './login';
|
||||
this.emailInput = page.locator('id=Email-input-field');
|
||||
this.passwordInput = page.locator('id=Password-input-field');
|
||||
this.submitBtn = page.locator('text=Login');
|
||||
}
|
||||
|
||||
async goto() {
|
||||
await this.page.goto(this.url);
|
||||
}
|
||||
|
||||
async enterEmail(email: string) {
|
||||
await this.emailInput.fill(email);
|
||||
}
|
||||
|
||||
async enterPassword(password: string) {
|
||||
await this.passwordInput.fill(password);
|
||||
}
|
||||
|
||||
async submitLogin() {
|
||||
await this.submitBtn.click();
|
||||
}
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
import { expect, Locator, Page } from '@playwright/test';
|
||||
|
||||
export class WelcomePage {
|
||||
readonly page: Page;
|
||||
readonly url: string;
|
||||
readonly profileLink: Locator;
|
||||
|
||||
constructor(page: Page){
|
||||
this.page = page;
|
||||
this.url = './overview';
|
||||
this.profileLink = page.locator('href=/profile');
|
||||
}
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
import type { PlaywrightTestConfig } from '@playwright/test';
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
globalSetup: require.resolve('./global-setup'),
|
||||
ignoreHTTPSErrors: true,
|
||||
locale: 'de-DE',
|
||||
reporter: process.env.CI ? 'github' : 'list',
|
||||
retries: 1,
|
||||
screenshot: 'only-on-failure',
|
||||
testDir: '.',
|
||||
timeout: 30000,
|
||||
trace: 'on-first-retry',
|
||||
video: 'never',
|
||||
viewport: { width: 1280, height: 720 },
|
||||
use: {
|
||||
baseURL: process.env.URL || 'http://127.0.0.1:3000',
|
||||
browserName: 'webkit',
|
||||
|
||||
},
|
||||
};
|
||||
export default config;
|
||||
Loading…
x
Reference in New Issue
Block a user