Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ jobs:
command: require gally/gally-premium:${{ env.composer_version }}
env:
COMPOSER_AUTH: ${{ secrets.COMPOSER_AUTH }}
- name: Install sample data package
working-directory: api
run: composer require "gally/gally-sample-data:${{ env.composer_version }} as ${{ inputs.last_published_version }}"
env:
COMPOSER_AUTH: ${{ secrets.COMPOSER_AUTH }}
- name: Pull images
run: ${{env.docker_compose_cmd}} pull --ignore-pull-failures || true
- name: Start services
Expand Down Expand Up @@ -144,6 +149,9 @@ jobs:
- name: Jest
run: ${{env.docker_compose_cmd}} exec -T pwa yarn test:ci

- name: e2e
run: ${{env.docker_compose_cmd}} exec -T e2e yarn test:ci

- name: Frontend Coverage Report
uses: 5monkeys/cobertura-action@v12
if: ${{ github.event_name == 'pull_request' }}
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ phpunit: ## Run php unit tests, pass the parameter "p=" to launch tests on a spe
jest: ## Run jest unit tests
@$(DOCKER_COMP) exec pwa yarn test

e2e: ## Run e2e tests
@$(DOCKER_COMP) exec e2e yarn test

jest_update: ## Run jest unit tests
@$(DOCKER_COMP) exec pwa yarn test:update

Expand Down
13 changes: 12 additions & 1 deletion compose.ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,28 @@ services:
environment:
- APP_ENV=dev
- XDEBUG_MODE=off
- TRUSTED_HOSTS=${TRUSTED_HOSTS:-^${SERVER_NAME:-|gally.localhost}|localhost|${E2E_SERVER_NAME:-gally.e2e}|php$$}

pwa:
build:
target: gally_pwa_ci
volumes:
- ./front/example-app/coverage:/usr/src/front/example-app/coverage:rw,cached,z
- ./front/pwa/coverage:/usr/src/front/pwa/coverage:rw,cached,z

environment:
- NEXT_PUBLIC_ENTRYPOINT=
- NEXT_PUBLIC_API_URL=
- REACT_APP_API_URL=
example:
build:
context: ./docker/front
target: gally_example_ci
additional_contexts:
front_src: ./front

e2e:
extends:
file: ./compose.e2e.yml
service: e2e
environment:
- CI=true
13 changes: 13 additions & 0 deletions compose.e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# E2E environment override
services:
e2e:
build:
context: .
dockerfile: ./docker/front/Dockerfile.e2e
environment:
- SERVER_BASE_URL=https://${E2E_SERVER_NAME:-gally.e2e}
- API_SERVER_BASE_URL=https://${E2E_SERVER_NAME:-gally.e2e}/${API_ROUTE_PREFIX:-api}
depends_on:
- proxy
extra_hosts:
- ${E2E_SERVER_NAME:-gally.e2e}:host-gateway
11 changes: 11 additions & 0 deletions compose.override.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ services:
- ./docker/php/conf.d/app.dev.ini:/usr/local/etc/php/conf.d/app.dev.ini:ro,z
environment:
- APP_ENV=${APP_ENV:-dev}
- TRUSTED_HOSTS=${TRUSTED_HOSTS:-^${SERVER_NAME:-|gally.localhost}|localhost|${E2E_SERVER_NAME:-gally.e2e}|php$$}
# See https://xdebug.org/docs/all_settings#mode
- XDEBUG_MODE=${XDEBUG_MODE:-off}
- PHP_IDE_CONFIG=serverName=gally
Expand All @@ -41,6 +42,9 @@ services:
environment:
# On Linux, you may want to comment the following line for improved performance
- WATCHPACK_POLLING="true"
- NEXT_PUBLIC_ENTRYPOINT=
- NEXT_PUBLIC_API_URL=
- REACT_APP_API_URL=

example:
user: ${UUID?You must set UUID env var}:${GUID?You must set GUID env var}
Expand All @@ -56,3 +60,10 @@ services:
environment:
- PUBLIC_URL=https://${SERVER_NAME:-gally.localhost}/example
- REACT_APP_API_URL=https://${SERVER_NAME:-gally.localhost}/${API_ROUTE_PREFIX:-api}

e2e:
extends:
file: ./compose.e2e.yml
service: e2e
volumes:
- ./front/e2e/:/usr/src/app:rw,cached,z
12 changes: 12 additions & 0 deletions docker/front/Dockerfile.e2e
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM mcr.microsoft.com/playwright:v1.39.0

WORKDIR /usr/src/app

COPY ./front/e2e/ .

RUN yarn install --frozen-lockfile

RUN npx playwright install chromium
RUN npx playwright install-deps chromium

CMD ["sleep", "infinity"]
5 changes: 5 additions & 0 deletions front/e2e/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
18 changes: 18 additions & 0 deletions front/e2e/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "e2e",
"private": "false",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"@playwright/test": "^1.47.2",
"@types/node": "^22.6.1"
},
"scripts": {
"test": "yarn playwright test",
"test:ci": "yarn playwright test",
"test:standard": "yarn playwright test --grep @standard",
"test:premium": "yarn playwright test --grep @premium"
},
"dependencies": {}
}
22 changes: 22 additions & 0 deletions front/e2e/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { defineConfig, devices } from '@playwright/test'

export default defineConfig({
testDir: './tests',
fullyParallel: false,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'line',
use: {
baseURL: process.env.SERVER_BASE_URL || "https://gally.local",
trace: 'on',
headless: true,
ignoreHTTPSErrors: true,
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
],
})
85 changes: 85 additions & 0 deletions front/e2e/tests/advanced/boost.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { test, expect } from '@playwright/test'
import { randomUUID } from 'crypto'
import { login } from '../helper/auth'
import { navigateTo } from '../helper/menu'
import { Dropdown } from '../helper/dropdown'

test('Boosts', async ({ page }) => {
await login(page)
await navigateTo(page, 'Boosts', '/fr/admin/merchandize/boost/grid')

const createButton = await page.getByTestId('createButtonResourceGrid')

/*
Grid Boost
*/
// TO DO

/*
Create Boost
*/
await createButton.click()
await expect(page).toHaveURL('/fr/admin/merchandize/boost/create')

// isActive Switch
const isActiveInput = await page.getByTestId('isActive')
const isActiveCheckbox = await isActiveInput.locator("input[type='checkbox']")

await expect(isActiveCheckbox).toBeChecked()
await isActiveInput.click()
await expect(isActiveCheckbox).not.toBeChecked()
await isActiveInput.click()
await expect(isActiveCheckbox).toBeChecked()

// Boost Preview
const previewFieldSet = await page.getByTestId('previewFieldSet')
await expect(
await previewFieldSet.getByTestId('previewRequiredMessage')
).toBeVisible()

// name InputText
const nameInput = await page.getByTestId('name')
const newName = randomUUID()

await expect(nameInput).toBeEmpty()
await nameInput.fill(newName)
await expect(nameInput).toHaveValue(newName)

// // Localized Catalogs Multiple Dropdown
const localizedCatalogs = new Dropdown(page, 'localizedCatalogs', true)
await localizedCatalogs.selectValue([
'COM French Catalog',
'COM English Catalog',
'FR French Catalog',
'EN French Catalog',
])

// Request types Multiple Dropdown
const requestTypesDropdown = new Dropdown(page, 'requestTypesDropdown', true)
await requestTypesDropdown.selectValue(['Category listing', 'Search result'])

// Model Dropdown
const modelDropdown = new Dropdown(page, 'model')
await modelDropdown.selectValue('Constante')

// Preview Boost Required Message
await expect(
await previewFieldSet.getByTestId('previewRequiredMessage')
).not.toBeVisible()

// Create the Boost and verify his existence
const saveButton = await page.getByTestId('submitButtonResourceForm')
await saveButton.click()
await expect(page).toHaveURL('/fr/admin/merchandize/boost/grid')
await expect(await page.getByText(newName)).toBeDefined() // TO DO : Manipulate the grid instead of research in the page.

/*
Edit Boost
*/
// TO DO

/*
Delete Boost
*/
// TO DO
})
45 changes: 45 additions & 0 deletions front/e2e/tests/basics/header.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { test, expect } from '@playwright/test'
import { login } from '../helper/auth'

test('Header', async ({ page }) => {
await login(page)

const appBar = await page.getByTestId('appBar')
const breadcrumbs = await appBar.getByTestId('breadcrumbs')
const tooltip = await appBar.getByTestId('helpToolTip')
const tooltipOver = await tooltip.getByTestId('helpOver')
const userMenu = await appBar.getByTestId('userMenu')

// Global Tests
await expect(breadcrumbs).toBeVisible()
await expect(tooltip).toBeVisible()
await expect(tooltipOver).not.toBeVisible()
await expect(userMenu).toBeVisible()

// ToolTip tests
await tooltip.hover()
await expect(tooltipOver).toBeVisible()

// UserMenu tests
const username = await userMenu.getByTestId('username')
const email = await userMenu.getByTestId('userEmail')
const logOutButton = await userMenu.getByTestId('logOutButton')

await expect(username).toBeVisible()
await expect(await username.innerText()).toBe('Admin@example.com')
await expect(email).not.toBeVisible()
await expect(logOutButton).not.toBeVisible()

await userMenu.click()

await expect(email).toBeVisible()
await expect(logOutButton).toBeVisible()
await expect(await email.innerText()).toBe('Admin@example.com')

await logOutButton.click()

await expect(page).toHaveURL(
`${process.env.SERVER_BASE_URL || 'https://gally.local'}/fr/login`
)
await login(page)
})
75 changes: 75 additions & 0 deletions front/e2e/tests/basics/leftMenu.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { test, expect } from '@playwright/test'
import { login } from '../helper/auth'

test('Menu', async ({ page }) => {
await login(page)

const sidebar = await page.getByTestId('sidebarMenu')
const collapseButton = await page.getByTestId('sidebarMenuCollapseButton')

const labelMenuItemIconList = await await page
.getByTestId('labelMenuItemIcon')
.all()
const menuItemChildrenButtonList = await page
.getByTestId('menuItemChildrenButton')
.all()
const menuItemChildrenList = await (
await page.getByTestId('menuItemChildren')
).all()
const labelMenuLinkItemList = await (
await page.getByTestId('labelMenuLinkItem')
).all()

for (const locator of menuItemChildrenList) {
await expect(locator).not.toBeVisible()
}

for (const locator of menuItemChildrenButtonList) {
await locator.click()
}

for (const locator of [...labelMenuLinkItemList, ...labelMenuItemIconList]) {
await expect(locator).toBeVisible()
}

const defaultSideBarWidth = (await sidebar.boundingBox())?.width

await expect(defaultSideBarWidth).not.toBe(undefined)

await collapseButton.click()

// Wait for menu transition to end
await page.evaluate(() => {
return new Promise<void>((resolve) => {
const element = document.querySelector('[data-testid="sidebarMenu"]')

element?.addEventListener('animationend', () => resolve(), {
once: true,
})
})
})

await expect((await sidebar.boundingBox())?.width).toBeLessThan(
defaultSideBarWidth as number
)

for (const locator of [...labelMenuLinkItemList, ...labelMenuItemIconList]) {
await expect(locator).not.toBeVisible()
}

await collapseButton.click()

await expect((await sidebar.boundingBox())?.width).toBe(defaultSideBarWidth)

for (const locator of [...labelMenuLinkItemList, ...labelMenuItemIconList]) {
await expect(locator).toBeVisible()
}

for (const locator of menuItemChildrenButtonList) {
await locator.click()
}

for (const locator of menuItemChildrenList) {
await expect(locator).not.toBeVisible()
}
})
Loading
Loading