Skip to content

Added: GitHub Action for E2E Tests Workflow on PRs#1692

Open
sumitwebkul wants to merge 3 commits intoQloapps:developfrom
sumitwebkul:e2e-github-action
Open

Added: GitHub Action for E2E Tests Workflow on PRs#1692
sumitwebkul wants to merge 3 commits intoQloapps:developfrom
sumitwebkul:e2e-github-action

Conversation

@sumitwebkul
Copy link
Copy Markdown
Collaborator

This pull request introduces a comprehensive end-to-end (E2E) testing setup for automating browser tests via GitHub Actions, ensuring robust CI/CD integration, and preparing the codebase for PHP 8.1+.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a Playwright-based E2E testing harness and a GitHub Actions workflow to automatically install QloApps in CI, start a PHP built-in server, and run browser tests on PRs/pushes—while also updating PHP version requirements.

Changes:

  • Added Playwright config, env template, CI router, and an initial “Customer Login” E2E spec.
  • Added a GitHub Actions workflow to provision MySQL, install QloApps, run Playwright, and upload reports/artifacts.
  • Updated composer.json PHP requirement and introduced a root package.json for Playwright tooling.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
.github/workflows/e2e-tests.yml CI workflow to install QloApps, start PHP server, execute Playwright, upload artifacts
composer.json Updates required PHP version range
package.json Adds Node devDependencies and scripts for running Playwright E2E tests
tests/e2e/playwright/playwright.config.ts Playwright test runner configuration + dotenv loading
tests/e2e/playwright/.env.example Template env vars for local/CI E2E runs
tests/e2e/playwright/ci-router.php Router for PHP built-in server to serve app + static files
tests/e2e/playwright/specs/website/auth/login.spec.ts Login/logout E2E scenarios
tests/e2e/**/index.php files Directory index redirects to prevent browsing test directories

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread composer.json
{
"require": {
"php": ">=5.4 <8.0",
"php": ">=8.1 <8.6",
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

composer.json allows PHP <8.6, which implies compatibility with PHP 8.5.x as well. The README currently states support is "PHP 8.1+ to PHP 8.4"; consider tightening the constraint (e.g., <8.5) or updating the documentation so the supported PHP range is consistent.

Suggested change
"php": ">=8.1 <8.6",
"php": ">=8.1 <8.5",

Copilot uses AI. Check for mistakes.
Comment on lines +4 to +5
# Base URL of the application under test
BASE_URL=http://127.0.0.1
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BASE_URL is documented as http://127.0.0.1 (no trailing slash), but the tests build URLs via string concatenation (e.g., BASE_URL + 'index.php?...'). With the example value, this produces an invalid URL (http://127.0.0.1index.php?...). Consider either normalizing BASE_URL to always end with / or constructing URLs via new URL() in the tests, and update the example accordingly.

Suggested change
# Base URL of the application under test
BASE_URL=http://127.0.0.1
# Base URL of the application under test (include trailing slash)
BASE_URL=http://127.0.0.1/

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +20
SQL_INJECTION_EMAIL=' OR '1'='1
XSS_EMAIL=<script>alert('xss')</script>
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SQL_INJECTION_EMAIL example value is wrapped in single quotes but itself contains single quotes, which can cause dotenv parsers to terminate the value early (and produce an unintended value). Use a representation that dotenv can parse reliably (e.g., wrap the whole value in double quotes or escape the embedded quotes).

Suggested change
SQL_INJECTION_EMAIL=' OR '1'='1
XSS_EMAIL=<script>alert('xss')</script>
SQL_INJECTION_EMAIL="' OR '1'='1"
XSS_EMAIL="<script>alert('xss')</script>"

Copilot uses AI. Check for mistakes.
test.describe('Customer Login', () => {

const BASE_URL = process.env.BASE_URL || 'http://127.0.0.1/';
const AUTH_URL = BASE_URL + 'index.php?controller=authentication';
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AUTH_URL is built via string concatenation from BASE_URL. If BASE_URL is set without a trailing slash (as in the provided .env.example), the resulting URL is invalid. Normalize BASE_URL (ensure exactly one trailing /) or build AUTH_URL via new URL('index.php?...', BASE_URL) to avoid configuration-dependent failures.

Suggested change
const AUTH_URL = BASE_URL + 'index.php?controller=authentication';
const AUTH_URL = new URL('index.php?controller=authentication', BASE_URL).toString();

Copilot uses AI. Check for mistakes.
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: 0,
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says "Retry on CI only", but retries is set to 0, which also makes trace: 'on-first-retry' a no-op (no retries => no trace capture). Either enable retries on CI (and keep the trace setting) or change the trace setting to one that matches the no-retry policy.

Suggested change
retries: 0,
retries: process.env.CI ? 2 : 0,

Copilot uses AI. Check for mistakes.
Comment on lines +6 to +7

if ($requestPath !== '/' && is_file($targetPath)) {
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The router concatenates $rootDirectory and the raw request path to decide whether to serve a static file. Without normalizing/validating the path (e.g., rejecting .. segments and ensuring the resolved path stays under $rootDirectory), this can open path traversal / unintended file serving when used with the built-in PHP server. Consider using realpath() + prefix check (or a strict whitelist) before returning false.

Suggested change
if ($requestPath !== '/' && is_file($targetPath)) {
$realTargetPath = realpath($targetPath);
if (
$requestPath !== '/' &&
$realTargetPath !== false &&
strncmp($realTargetPath, $rootDirectory . DIRECTORY_SEPARATOR, strlen($rootDirectory) + 1) === 0 &&
is_file($realTargetPath)
) {

Copilot uses AI. Check for mistakes.
Comment on lines +131 to +141
cat > tests/e2e/playwright/.env << EOF
BASE_URL=$BASE_URL
CUSTOMER_EMAIL=$CUSTOMER_EMAIL
CUSTOMER_PASSWORD=$CUSTOMER_PASSWORD
INVALID_EMAIL=$INVALID_EMAIL
INVALID_PASSWORD=$INVALID_PASSWORD
INVALID_EMAIL_FORMAT=$INVALID_EMAIL_FORMAT
SQL_INJECTION_EMAIL=$SQL_INJECTION_EMAIL
XSS_EMAIL=$XSS_EMAIL
EOF

Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The generated .env file writes values without robust escaping/quoting. Values like SQL_INJECTION_EMAIL contain spaces and quotes, which can break dotenv parsing (or change the value) and make local/CI behavior diverge. Either (a) remove this step and rely on the job-level env: already set, or (b) emit correctly quoted dotenv values (e.g., wrap in double quotes and escape embedded characters).

Suggested change
cat > tests/e2e/playwright/.env << EOF
BASE_URL=$BASE_URL
CUSTOMER_EMAIL=$CUSTOMER_EMAIL
CUSTOMER_PASSWORD=$CUSTOMER_PASSWORD
INVALID_EMAIL=$INVALID_EMAIL
INVALID_PASSWORD=$INVALID_PASSWORD
INVALID_EMAIL_FORMAT=$INVALID_EMAIL_FORMAT
SQL_INJECTION_EMAIL=$SQL_INJECTION_EMAIL
XSS_EMAIL=$XSS_EMAIL
EOF
python - << 'PY'
import os
import json
from pathlib import Path
env_path = Path("tests/e2e/playwright/.env")
keys = [
"BASE_URL",
"CUSTOMER_EMAIL",
"CUSTOMER_PASSWORD",
"INVALID_EMAIL",
"INVALID_PASSWORD",
"INVALID_EMAIL_FORMAT",
"SQL_INJECTION_EMAIL",
"XSS_EMAIL",
]
env_path.parent.mkdir(parents=True, exist_ok=True)
with env_path.open("w", encoding="utf-8") as f:
for key in keys:
value = os.environ.get(key, "")
f.write(f"{key}={json.dumps(value)}\n")
PY

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants