Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/playwright migration #78

Merged
merged 74 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
e17f3ad
added playwright foundations
Apr 3, 2023
3071fbe
feat: added isBootstrap5 function
Apr 5, 2023
845af4e
fix: docker failing to build on windows
dragonflyfree Apr 5, 2023
4f1c9ac
fix: removing node modules
dragonflyfree Apr 5, 2023
a5aa9ec
Expanded helper functions, added Timelog tests
dragonflyfree Apr 13, 2023
b32e99c
adding test file timelog.test.ts
dragonflyfree Apr 13, 2023
65969b3
Find rows
dragonflyfree Apr 14, 2023
5aacbbd
feat: added playwright config
Apr 14, 2023
ee9ce6e
Working on timelog helper
dragonflyfree Apr 14, 2023
07f343b
Merge branch 'feature/PlaywrightMigration' of github.com:2pisoftware/…
dragonflyfree Apr 14, 2023
14d0da3
Adding admin tests/helper functions
dragonflyfree Apr 19, 2023
163fa1f
Fixing acceptDialog error
dragonflyfree Apr 20, 2023
25e2b93
Adding CmfiveHelper file
dragonflyfree Apr 20, 2023
1f0d260
Speeding things up
dragonflyfree Apr 20, 2023
2f51a6f
Reducing timeout for admin helpers checking URL
dragonflyfree Apr 20, 2023
199916d
working on admin lookup test
dragonflyfree Jun 1, 2023
4bd7129
feat: added channels module test
dragonflyfree Jun 14, 2023
2efaa5d
feat: add task, form module tests:
dragonflyfree Jun 23, 2023
23f2b1c
fix: uncomment admin/channels tests
dragonflyfree Jun 23, 2023
65ceebd
fix: fix issue with form application saving
Jun 23, 2023
6d97c19
add readme and gitignore
dragonflyfree Aug 10, 2023
911f273
Merge pull request #74 from 2pisoftware/feat/PlaywrightMigration-roll…
dragonflyfree Aug 10, 2023
5f6951a
fix: updating readme
dragonflyfree Aug 15, 2023
44d5463
fix: adding uniqueness to admin lookup tests, fixing form module test
dragonflyfree Sep 8, 2023
d85f40b
fix: updating Admin tests for Boostrap5
dragonflyfree Sep 8, 2023
85c9057
feat: adding migration test, fixing lookup/templates tests
dragonflyfree Sep 12, 2023
74f150c
fix: updating migration test for new design
dragonflyfree Sep 19, 2023
cae1f7a
fix: changing Channels test to expect full pages instead of modals
dragonflyfree Oct 10, 2023
bc9285b
add script for cleaning up test migration files
dragonflyfree Nov 6, 2023
88fc87c
update playwright setup readme
dragonflyfree Nov 6, 2023
83e3d81
test files/test util files now live with their respective modules
dragonflyfree Nov 10, 2023
65ad8eb
updating laywright readme instructions
dragonflyfree Nov 10, 2023
6372c32
update readme to suggest using feature/AdminBS5Conversion instead of …
dragonflyfree Nov 10, 2023
0d7e55a
adding extra clarity to playwright readme
dragonflyfree Nov 10, 2023
0a076f9
playwright setup helper script now looks for pre-existing test/tsconf…
dragonflyfree Nov 13, 2023
3948b67
fix: tests check data-layout attr on html for determining page layout
dragonflyfree Nov 14, 2023
2931ca7
updating playwright readme
dragonflyfree Nov 17, 2023
474181d
add clean db setup steps to readme
dragonflyfree Nov 17, 2023
b464da4
remove system from commit tree
adam-buckley Nov 28, 2023
9b2be48
fix: lookup test fix
Nov 30, 2023
00020c4
Merge branch 'feature/PlaywrightMigration' of github.com:2pisoftware/…
Nov 30, 2023
02e685e
13 tests run on chrome, chromium, firefox, msedge platforms
dragonflyfree Dec 1, 2023
962245a
feat: working on test runner script for playwright
Dec 4, 2023
5daa9d7
feat: working on test runner script for playwright
Dec 4, 2023
e0c2470
fix: remove system symlink from git tree
Dec 4, 2023
6509ff7
fix: (re)added Claires npm scripts
Dec 5, 2023
2ff3c7f
feat: added support for reporter
Dec 5, 2023
e482f5f
feat: added support for reporter
Dec 5, 2023
037f79a
feat: added support for reporter
Dec 5, 2023
2ae316c
Merge branch 'feature/PlaywrightMigration' of github.com:2pisoftware/…
adam-buckley Dec 6, 2023
c131cde
fix: clean up git tree
Dec 7, 2023
208f7e0
merge develop into playwright migration feature branch
dragonflyfree Dec 8, 2023
535e235
fix isBoostrap5 helper methodC
dragonflyfree Dec 8, 2023
9e1ffd3
nothing to see here
dragonflyfree Dec 8, 2023
474a161
fix: update gitignore
Dec 11, 2023
4393018
update readme, npm scripts, and default test timeout
dragonflyfree Dec 11, 2023
d9ad4b6
git catchup
dragonflyfree Dec 11, 2023
b841657
add bash script for running playwright tests with retries for CI
dragonflyfree Dec 12, 2023
fb4d501
update playwright run test with retries script
dragonflyfree Dec 12, 2023
e038a51
update readme
dragonflyfree Dec 12, 2023
be0dd5b
remove cautionary build step for npm run test, update readme
dragonflyfree Dec 12, 2023
7c61fa7
fix: fixed getRowByText
Dec 13, 2023
0272662
Merge branch 'feature/PlaywrightMigration' of github.com:2pisoftware/…
Dec 13, 2023
abfab83
fix: fix cmfive utils
Dec 13, 2023
26d5c91
fix: trying to fix isBootstrap5 race condition
Dec 13, 2023
428ba50
Merge branch 'feature/PlaywrightMigration' of github.com:2pisoftware/…
dragonflyfree Dec 13, 2023
6907a5c
feat: fancier playwright test retry scripts for dev/CI, readme updated
dragonflyfree Dec 13, 2023
aea642e
fix: remove run test with retries exit statements so whole CI playwri…
dragonflyfree Dec 14, 2023
000401d
fix: CI not failing when a module test fails
dragonflyfree Dec 14, 2023
12a1490
fixcorrecting run-test-with-retries.sh alert text
dragonflyfree Dec 14, 2023
b50078f
fix: cmfive util
Dec 14, 2023
e2817bd
fix: remove logs
Dec 14, 2023
bb8d4a4
Merge branch 'feature/PlaywrightMigration' of github.com:2pisoftware/…
Dec 14, 2023
b8947f3
fix: updating readme.md
Jan 15, 2024
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
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Convert to LF line endings on checkout.
*.sh text eol=lf
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,10 @@ venv/
.build/environment/dev/Dockerfile

.build/environment/prod/stage/
.build/environment/prod/Dockerfile
.build/environment/prod/Dockerfile

# Playwright Files
test/playwright/node_modules/
test/playwright/test-results/
test/playwright/src/
test/playwright/*.png
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,5 @@ COPY /.codepipeline/local-dev/configs/supervisord/supervisord.conf /etc/supervis

RUN mkdir /run/php

RUN chmod -R 777 start.sh
CMD ["/bootstrap/start.sh"]
RUN chmod -R 777 /bootstrap/start.sh
CMD ["/bootstrap/start.sh"]
30 changes: 30 additions & 0 deletions test-cli.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env bash

# Verify that we have arguments
if [ $# -eq 0 ]
then
echo "No arguments supplied"
fi

echo "Running $1 tests (reporter: $2)"

SCRIPT_DIR=$(pwd)

MODULE=$1
REPORTER=${2:-"list"}
BROWSER="${3@Q}"
# Go into Playwright test directory
cd test/playwright

# Run tests
npm run build

if [ -z "$BROWSER" ]
then
npx playwright test --reporter $REPORTER --grep "$MODULE"
else
npx playwright test --project $BROWSER --reporter $REPORTER --grep "$MODULE"
fi

# Go back to script directory
cd $SCRIPT_DIR
3 changes: 3 additions & 0 deletions test/playwright/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.png

playwright-report/
60 changes: 60 additions & 0 deletions test/playwright/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Get Cmfive Working

- Bring cmfive up using standard docker compose tools
- Wait for everything to be setup, then right click on the nginx webapp container and `Open In Browser`
- If the webpage gives a MONOLOGGER error, run `bash ./.codespaces/scripts/02_postCreateScript.sh`
- If not, Cmfive is ready for your Playwright tests

# Download nvm

- Grab the latest version of nvm from https://nvm.sh using the `curl` command
- Close the current terminal after nvm is downloaded, and open a new terminal
- `nvm install 18`
- `nvm use 18`

# Use the develop branch as the cmfive-boilerplate repo

- `cd cmfive-boilerplate`
- `git switch develop`

# Use the develop branch as the cmfive-core repo

- `cd ../cmfive-core`
- `git switch develop`

# Ensure styles are compiled

- `cd ./composer/vendor/2pisoftware/cmfive-core/system/templates/base`
- `npm i`
- `npm run dev`

# Setup Playwright

- `cd ../../../../cmfive-boilerplate/test/playwright`
- `npm i`
- `npx playwright install`
- `npx playwright install-deps`
- `npm run setup`
- `npm run build` (run this every time you have changes to a test or utils file that you want to include in the next test run, and for utils files specifically those changes to be present when importing via `@utils/*`)

# Run Playwright Tests

- cwd should be `cmfive-boilerplate/test/playwright/`
- `npm run cleanup` (important! do this every time before you run tests on a system after already having done so previously)
- `npm run test`
- to run tests for a specific platform: `npm run test --platform="[insert browser]"`
- Example: `npm run test --platform="firefox"`
- to run a specific test file: `npm run test --module="[insert test file name]"`
- Example: `npm run test --module="admin"`
- see: https://playwright.dev/docs/test-cli (look for `--grep` instead of `--module`)
- if you want your tests to be attempted a certain number of times (for flaky tests) when they fail: `npm run test:with-retries`
- Example: `npm run test:with-retries --module="task|timelog" --attempts=2 --clean` (`--clean` runs `npm run cleanup` BEFORE your tests run if you have a possibly dirty setup, the script automatically handles the rest of the cleanups for retries)

# Setting up a new Playwright test for a module

- cd into the top level of the module (for example, cwd could be `cmfive-core/system/modules/help`)
- `bash /workspaces/codespace_dev_box/cmfive-boilerplate/test/playwright/mapToPlaywright.sh`
- the above script should be run whenever the relative path between a module and the base playwright directory in `cmfive-boilerplate` changes
- `*.test.ts` files contain the actual test code
- `*.utils.ts` files contain utility functions for a given module
- util files are imported like so: `import { AdminHelper } from '@utils/admin'`, without `.utils.ts` file extension
34 changes: 34 additions & 0 deletions test/playwright/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const glob = require('glob');
const fs = require('fs');
const path = require('path');

function copyFiles(sourceGlob, destDir, rename = fileName => fileName) {
// Find all files and directories that match the glob pattern
glob(sourceGlob, { nodir: true }).then(files => {
// Create the destination directory if it doesn't exist
if (!fs.existsSync(destDir)) {
fs.mkdirSync(destDir);
}

// Copy each file to the destination directory
files.forEach(file => {
const fileName = rename(path.basename(file));
const destFile = path.join(destDir, fileName);
fs.copyFileSync(file, destFile);
});
}).catch(err => {
console.error(err);
})
}

// pull all module test files into src directory
copyFiles('../../system/modules/**/tests/acceptance/playwright/*.test.ts', './src')
copyFiles('../../modules/**/tests/acceptance/playwright/*.test.ts', './src')

// pull all module test util files into one directory for scoping
copyFiles('../../system/modules/**/tests/acceptance/playwright/*.utils.ts', './src/utils',
fileName => fileName.replace('.utils.ts', '.ts')
);
copyFiles('../../modules/**/tests/acceptance/playwright/*.utils.ts', './src/utils',
fileName => fileName.replace('.utils.ts', '.ts')
);
55 changes: 55 additions & 0 deletions test/playwright/cleanupTestMigrations.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/bash

BASE_DIR="../../system/modules"

matches=$(find "$BASE_DIR" -path "*/install/migrations/*_TestMigration.php")

if [ -z "$matches" ]; then
echo -e "\n\033[0;33mNo migration test files found.\033[0m"
exit 0
fi

declare -a deletable
declare -a undeletable

for file in $matches; do
if [ -f "$file" ] && [ -w "$(dirname "$file")" ]; then
deletable+=("$file")
else
undeletable+=("$file")
fi
done

if [ ${#undeletable[@]} -ne 0 ]; then
echo -e "\n\033[0;41mThese files cannot be deleted using the current permissions (you might need to use sudo):\033[0m"
echo -e -n "\033[0;31m"
for file in "${undeletable[@]}"; do
echo " $file"
done
echo -e -n "\033[0m"
fi

if [ ${#deletable[@]} -ne 0 ]; then
echo -e "\n\033[0;42mThese files can be deleted using the current permissions:\033[0m"

echo -e -n "\033[0;32m"
for file in "${deletable[@]}"; do
echo " $file"
done
echo -e -n "\033[0m"

echo
echo -e "\033[0;33m"
read -p "Do you want to delete the files you have permission to delete? (y/n) " confirm_delete
echo -e "\033[0m"

if [[ "$confirm_delete" =~ ^[Yy]$ ]]; then
for file in "${deletable[@]}"; do
rm -v "$file"
done
else
echo "No files deleted."
fi
else
echo -e "\nThere are no files to delete with the current permissions."
fi
73 changes: 73 additions & 0 deletions test/playwright/cmfive.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Page, expect } from "@playwright/test";
import { DateTime } from "luxon";

export const HOST = (process.env.TEST_HOST ?? "http://127.0.0.1") + ":" + (process.env.TEST_PORT ?? "3000");
export const GLOBAL_TIMEOUT = +(process.env.TIMEOUT ?? 30_000);

export class CmfiveHelper {
static randomID = (prefix: string) => prefix + (Math.random() + 1).toString(36).substring(7)

static async login(page: Page, user: string, password: string)
{
await page.goto(HOST + "/auth/login");
await page.locator("#login").fill(user);
await page.locator("#password").fill(password);
await page.getByRole("button", {name: "Login"}).click();
}

static async logout(page: Page)
{
await page.goto(HOST + "/auth/logout");
}

static async isBootstrap5(page: Page)
{
try {
await page.locator('.body')
} catch (e) {
await page.waitForSelector('.body');
}
return await page.locator('html.theme').count() > 0
}

static getRowByText(page: Page, text: string)
{
return page.locator("tr", { has: page.getByText(text, {exact: true}) }); // page.locator('tr:has-text("' + text + '")');
}

static async clickCmfiveNavbar(page: Page, category: string, option: string)
{
const navbarCategory = page.locator("#topnav_" + category.toLowerCase().split(" ").join("_"));
const bootstrap5 = await this.isBootstrap5(page);
if (bootstrap5) {
await navbarCategory.click();
} else { // Foundation
await navbarCategory.hover();
}

await navbarCategory.getByText(option).click();
}

// Call exactly once per test before any dialogs pop up
static async acceptDialog(page: Page)
{
page.on('dialog', dialog => dialog.accept());
}

static async fillDatePicker(page: Page, datePickerTitle: string, field: string, date: DateTime) {
await page.getByText(datePickerTitle).click();
await page.keyboard.type(date.toFormat("ddLLyyyy"));

const expectedDate = date.toISODate();
if(expectedDate == null)
throw new Error("date.toISODate() returned null");
else
await expect(page.locator("#" + field)).toHaveValue(expectedDate);
}

static async fillAutoComplete(page: Page, field: string, search: string, value: string) {
await page.locator('#acp_' + field).click();
await page.keyboard.type(search);
await page.locator('.ui-menu-item :text("' + value + '")').click();
}
}
37 changes: 37 additions & 0 deletions test/playwright/mapToPlaywright.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash

to_relative_path() {
# The target path is the first argument
local target_path=$1

# The base path is the second argument or the current working directory if not provided
local base_path=${2:-$(pwd)}

# Use realpath command to compute the relative path
echo "$(realpath --relative-to="$base_path" "$target_path")"
}

# Get name of module and create playwright test directory structure
module_name=$(basename $(pwd))
mkdir -p ./tests/acceptance/playwright/

# Get the absolute path of the base playwright directory (the directory containing this script)
playwright_dir_abs=$(cd $(dirname "$0") && pwd -P)

# Get relative path to the base playwright directory from module's playwright test directory
playwright_dir_rel=$(to_relative_path $playwright_dir_abs ./tests/acceptance/playwright/)

# Check if the playwright test file for the module already exists
if [ ! -f ./tests/acceptance/playwright/${module_name}.test.ts ]; then
# Copy boilerplate test file to module's playwright test directory if test file not present
cp $playwright_dir_abs/test_boilerplate.ts ./tests/acceptance/playwright/${module_name}.test.ts
fi

# Check if tsconfig.json exists
if [ -f ./tests/acceptance/playwright/tsconfig.json ]; then
# Update the baseUrl of the pre-existing tsconfig.json
jq --arg playwright_dir_rel "$playwright_dir_rel" '.compilerOptions.baseUrl = $playwright_dir_rel' ./tests/acceptance/playwright/tsconfig.json > ./tests/acceptance/playwright/tsconfig.tmp.json && mv ./tests/acceptance/playwright/tsconfig.tmp.json ./tests/acceptance/playwright/tsconfig.json
else
# Generate new tsconfig.json if it doesn't exist
jq --arg playwright_dir_rel "$playwright_dir_rel" '.compilerOptions.baseUrl = $playwright_dir_rel' $playwright_dir_abs/test_boilerplate.tsconfig.json > ./tests/acceptance/playwright/tsconfig.json
fi
Loading