Skip to content

Commit

Permalink
Merge pull request #236 from Progi1984/ciTestsUI
Browse files Browse the repository at this point in the history
Added UI Tests
  • Loading branch information
jolelievre authored Feb 20, 2024
2 parents dbaf532 + b96aa6d commit fb1ddd0
Show file tree
Hide file tree
Showing 19 changed files with 1,550 additions and 1 deletion.
16 changes: 16 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: 2
updates:
- package-ecosystem: npm
directory: "/tests/UI"
schedule:
interval: weekly
day: monday
time: "04:00"
open-pull-requests-limit: 10
target-branch: dev
reviewers:
- "PrestaShop/qa-automation"
labels:
- "dependencies"
- "E2E Tests"
- "TE"
110 changes: 110 additions & 0 deletions .github/workflows/ui-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: UI Tests
on:
## Check each PR
push:
pull_request:
## Manual execution on branch
workflow_dispatch:
## Nightly
### Needs secrets
#### GC_PROJECT_ID
#### GC_SERVICE_KEY
#### NIGHTLY_TOKEN
schedule:
- cron: '0 0 * * *'
jobs:
ui_test:
name: UI Tests
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- ps-version: '8.0.5'
php-version: '8.1'
- ps-version: '8.1.4'
php-version: '8.1'
- ps-version: 'nightly'
php-version: '8.2'
env:
PS_VERSION: ${{ matrix.ps-version }}
PHP_VERSION: ${{ matrix.php-version }}
steps:
- name: Checkout
uses: actions/[email protected]

- uses: actions/setup-node@v3
with:
node-version: 14

- name: Build
run: npm install && npm run build

- name: Start containers
working-directory: tests/UI/
run: |
docker-compose -f "docker-compose.yml" up -d --build
bash -c 'while [[ "$(curl -L -s -o /dev/null -w %{http_code} http://localhost/en/)" != "200" ]]; do sleep 5; done'
- name: Install dependencies
working-directory: tests/UI/
run: npm ci

- name: Install Playwright Browsers
working-directory: tests/UI/
run: npx playwright install chromium --with-deps

- name: Run Playwright tests
working-directory: tests/UI/
run: npx playwright test

- name: Export Docker errors
working-directory: tests/UI/
if: always()
run: docker-compose logs --no-color >& docker-compose.log

- name: Upload artifact
uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report-${{ env.PS_VERSION }}
path: |
tests/UI/reports/
tests/UI/report.json
tests/UI/docker-compose.log
retention-days: 30

# Nightly : Rename file
- name: "Nightly : Rename file"
working-directory: tests/UI/
if: ${{ github.event_name == 'schedule' }}
run: |
mkdir -p nightly
REPORT_NAME="blockwishlist_$(date +%Y-%m-%d)-${{ env.PS_VERSION }}"
mv report.json nightly/${REPORT_NAME}.json
# Nightly : Auth GCP
- name: "Nightly : Auth GCP"
uses: google-github-actions/auth@v1
if: ${{ github.event_name == 'schedule' }}
with:
credentials_json: ${{ secrets.GC_SERVICE_KEY }}
project_id: ${{ secrets.GC_PROJECT_ID }}

# Nightly : Setup GCP
- name: "Nightly : Setup GCP"
uses: google-github-actions/setup-gcloud@v1
if: ${{ github.event_name == 'schedule' }}

# Nightly : Upload to Google Cloud Storage (GCS)
- name: "Nightly : Upload to Google Cloud Storage (GCS)"
working-directory: tests/UI/
if: ${{ github.event_name == 'schedule' }}
run: gsutil cp -r "nightly/**" gs://prestashop-core-nightly/reports

# Nightly : Push Report
- name: "Nightly : Push Report"
if: ${{ github.event_name == 'schedule' }}
run: |
REPORT_NAME="blockwishlist_$(date +%Y-%m-%d)-${{ env.PS_VERSION }}"
curl -v "https://api-nightly.prestashop-project.org/import/report/playwright?token=${{ secrets.NIGHTLY_TOKEN }}&filename=${REPORT_NAME}.json"
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,9 @@ node_modules

# mac
.DS_Store

## UI Tests
/tests/UI/.env
/tests/UI/node_modules/
/tests/UI/report.json
/tests/UI/reports/
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"watch": "npm run dev",
"lint": "eslint -c .eslintrc.js --ext .js,.vue .",
"lint-fix": "eslint -c .eslintrc.js --ext .js,.vue . --fix",
"test": "mochapack --webpack-config .webpack/common.js --require tests/UI/setup.js tests/UI/**/*.spec.js"
"test": "mochapack --webpack-config .webpack/common.js --require tests/js/setup.js tests/js/**/*.spec.js"
},
"author": "PrestaShop",
"license": "AFL-3.0",
Expand Down
175 changes: 175 additions & 0 deletions tests/UI/campaigns/02_configuration/02_statisticsTabSettings.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import {
// Import utils
testContext,
// Import BO pages
boDashboardPage,
boLoginPage,
boModuleManagerPage,
// Import FO pages
foCategoryPage,
foHomePage,
foLoginPage,
// Import modules
modBlockwishlistBoMain,
modBlockwishlistBoStatistics,
// Import data
dataCustomers,
dataModules,
} from '@prestashop-core/ui-testing';

import { test, expect, Page, BrowserContext } from '@playwright/test';

const baseContext: string = 'modules_blockwishlist_configuration_statisticsTabSettings';

test.describe('Wishlist module - Statistics tab settings', () => {
let browserContext: BrowserContext;
let page: Page;

test.beforeAll(async ({ browser }) => {
browserContext = await browser.newContext();
page = await browserContext.newPage();
});
test.afterAll(async () => {
await page.close();
});

test('should login in BO', async () => {
await testContext.addContextItem(test.info(), 'testIdentifier', 'loginBO', baseContext);

await boLoginPage.goTo(page, global.BO.URL);
await boLoginPage.successLogin(page, global.BO.EMAIL, global.BO.PASSWD);

const pageTitle = await boDashboardPage.getPageTitle(page);
expect(pageTitle).toContain(boDashboardPage.pageTitle);
});

test('should go to \'Modules > Module Manager\' page', async () => {
await testContext.addContextItem(test.info(), 'testIdentifier', 'goToModuleManagerPage', baseContext);

await boDashboardPage.goToSubMenu(
page,
boDashboardPage.modulesParentLink,
boDashboardPage.moduleManagerLink,
);
await boModuleManagerPage.closeSfToolBar(page);

const pageTitle = await boModuleManagerPage.getPageTitle(page);
expect(pageTitle).toContain(boModuleManagerPage.pageTitle);
});


test(`should search the module ${dataModules.blockwishlist.name}`, async () => {
await testContext.addContextItem(test.info(), 'testIdentifier', 'searchModule', baseContext);

const isModuleVisible = await boModuleManagerPage.searchModule(page, dataModules.blockwishlist);
expect(isModuleVisible).toEqual(true);
});

test(`should go to the configuration page of the module '${dataModules.blockwishlist.name}'`, async () => {
await testContext.addContextItem(test.info(), 'testIdentifier', 'goToConfigurationPage', baseContext);

await boModuleManagerPage.goToConfigurationPage(page, dataModules.blockwishlist.tag);

const pageTitle = await modBlockwishlistBoMain.getPageTitle(page);
expect(pageTitle).toEqual(modBlockwishlistBoMain.pageTitle);

const isConfigurationTabActive = await modBlockwishlistBoMain.isTabActive(page, 'Configuration');
expect(isConfigurationTabActive).toEqual(true);

const isStatisticsTabActive = await modBlockwishlistBoMain.isTabActive(page, 'Statistics');
expect(isStatisticsTabActive).toEqual(false);
});

test('should go on Statistics Tab', async () => {
await testContext.addContextItem(test.info(), 'testIdentifier', 'goToStatisticsTab', baseContext);

await modBlockwishlistBoMain.goToStatisticsTab(page);

const pageTitle = await modBlockwishlistBoStatistics.getPageTitle(page);
expect(pageTitle).toEqual(modBlockwishlistBoStatistics.pageTitle);

const noRecordsFoundText = await modBlockwishlistBoStatistics.getTextForEmptyTable(page);
expect(noRecordsFoundText).toContain('warning No records found');
});

test('should go to the FO', async () => {
await testContext.addContextItem(test.info(), 'testIdentifier', 'goToFO', baseContext);

page = await modBlockwishlistBoStatistics.viewMyShop(page);
await foHomePage.changeLanguage(page, 'en');

const isHomePage = await foHomePage.isHomePage(page);
expect(isHomePage).toEqual(true);
});

test('should go to login page', async () => {
await testContext.addContextItem(test.info(), 'testIdentifier', 'goToLoginPage', baseContext);

await foHomePage.goToLoginPage(page);

const pageTitle = await foLoginPage.getPageTitle(page);
expect(pageTitle, 'Fail to open FO login page').toContain(foLoginPage.pageTitle);
});

test('should sign in with default customer', async () => {
await testContext.addContextItem(test.info(), 'testIdentifier', 'sighInFo', baseContext);

await foLoginPage.customerLogin(page, dataCustomers.johnDoe);

const isCustomerConnected = await foLoginPage.isCustomerConnected(page);
expect(isCustomerConnected, 'Customer is not connected').toEqual(true);
});

test('should go to all products page', async () => {
await testContext.addContextItem(test.info(), 'testIdentifier', 'goToAllProducts', baseContext);

await foHomePage.goToAllProductsPage(page);

const isCategoryPageVisible = await foCategoryPage.isCategoryPage(page);
expect(isCategoryPageVisible).toEqual(true);
});

for (let idxProduct: number = 1; idxProduct <= 3; idxProduct++) {
// eslint-disable-next-line no-loop-func
test(`should add product #${idxProduct} to wishlist`, async () => {
await testContext.addContextItem(test.info(), 'testIdentifier', `addToFavorite${idxProduct}`, baseContext);

const textResult = await foCategoryPage.addToWishList(page, idxProduct);
expect(textResult).toEqual(foCategoryPage.messageAddedToWishlist);

const isAddedToWishlist = await foCategoryPage.isAddedToWishlist(page, idxProduct);
expect(isAddedToWishlist).toEqual(true);
});
}

test('should logout', async () => {
await testContext.addContextItem(test.info(), 'testIdentifier', 'foLogout', baseContext);

await foCategoryPage.logout(page);

const isCustomerConnected = await foHomePage.isCustomerConnected(page);
expect(isCustomerConnected).toEqual(false);
});

test('should go to BO', async () => {
await testContext.addContextItem(test.info(), 'testIdentifier', 'goToBoBack', baseContext);

page = await foHomePage.closePage(browserContext, page, 0);

const pageTitle = await modBlockwishlistBoStatistics.getPageTitle(page);
expect(pageTitle).toContain(modBlockwishlistBoStatistics.pageTitle);
});

// @todo : https://github.com/PrestaShop/PrestaShop/issues/33374
test('should click on the refresh button', async () => {
await testContext.addContextItem(test.info(), 'testIdentifier', 'clickOnRefreshButton', baseContext);

test.skip(true, 'https://github.com/PrestaShop/PrestaShop/issues/33374');

await modBlockwishlistBoStatistics.refreshStatistics(page);

// Check statistics
const pageTitle = await modBlockwishlistBoStatistics.getPageTitle(page);
expect(pageTitle).toContain(modBlockwishlistBoStatistics.pageTitle);
});
});
54 changes: 54 additions & 0 deletions tests/UI/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
version: '3.7'

services:
prestashop:
image: prestashop/prestashop:${PS_VERSION}-${PHP_VERSION}-apache
container_name: prestashop
depends_on:
- mysql
environment:
- PS_DEV_MODE=1
- PS_DOMAIN=localhost
- PS_LANGUAGE=en
- PS_COUNTRY=fr
- PS_INSTALL_AUTO=1
- PS_FOLDER_ADMIN=admin-dev
- PS_FOLDER_INSTALL=install-dev
- PS_USE_DOCKER_MAILDEV=0
- [email protected]
- ADMIN_PASSWD=prestashop
- DB_SERVER=mysql
- DB_USER=prestashop
- DB_PASSWD=prestashop
- DB_NAME=prestashop
volumes:
- type: bind
# Local Path
source: ../../
# Mount Path
target: /var/www/html/modules/blockwishlist
ports:
- 80:80
mysql:
image: mariadb:lts
container_name: prestashop-mysql
healthcheck:
test:
[
'CMD',
'mysqladmin',
'ping',
'--host=localhost',
'--user=prestashop',
'--password=prestashop',
]
interval: 5s
timeout: 10s
retries: 5
environment:
- MYSQL_HOST=mysql
- MYSQL_USER=prestashop
- MYSQL_PASSWORD=prestashop
- MYSQL_ROOT_PASSWORD=prestashop
- MYSQL_PORT=3306
- MYSQL_DATABASE=prestashop
Loading

0 comments on commit fb1ddd0

Please sign in to comment.