Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
20a7d6c
feat!: add generic e2e support to check-store workflow
May 19, 2026
a7d8e30
fix: refine generic e2e workflow orchestration
May 19, 2026
863eab5
fix: guard remaining e2e runtime setup steps
May 19, 2026
3dea50b
fix: combined both checks package.json and e2e folder existence to tr…
May 19, 2026
9962aea
fix: refine e2e suite detection and orchestration flow
May 20, 2026
9a67bff
Remove unecessary code
May 22, 2026
ff27265
fix: add sample data and e2e suite bootstrap
Jun 2, 2026
f4a8d43
refactor: remove e2e workflow guards during validation
Jun 3, 2026
f5ad7cd
Fix matrix reference in check-store workflow
damienwebdev Jun 3, 2026
4bdd58b
feat(resolve-check-config): add support for check-store e2e-tests
damienwebdev Jun 10, 2026
26413af
fix a bad rebase
damienwebdev Jun 10, 2026
c456442
fix: fallback to npm install when lockfile is missing
Jun 11, 2026
b388bed
Merge branch 'graycoreio:main' into feat/check-store-e2e-support
digitalrisedorset Jun 18, 2026
71c20be
fix: bootstrap E2E suite from cloned MageOS repository
Jun 18, 2026
d16b002
feat: bootstrap Playwright E2E suite for Check Store
Jun 18, 2026
56451eb
debug: inspect E2E suite installation in CI
Jun 18, 2026
36f1e8e
chore: remove temporary E2E debugging
Jun 18, 2026
c80125c
ci(e2e): split initial Playwright smoke tests
Jun 18, 2026
1e4e25b
fix(ci): run Playwright tests from E2E working directory
Jun 18, 2026
cdc0bf8
feat(ci): publish Playwright reports and test artifacts
Jun 23, 2026
ed78052
feat(ci): install Playwright browsers with system dependencies
Jun 23, 2026
b343d06
chore(ci): enable E2E setup steps for debugging
Jun 23, 2026
765f6ed
chore(ci): remove E2E step conditions for debugging
Jun 24, 2026
0ab7aed
chore(ci): use Node.js 22 for E2E workflow
Jun 25, 2026
2beb482
chore(ci): use Node.js 24 for E2E workflow
Jun 25, 2026
a136e0c
chore(ci): remove npm cache from E2E setup
Jun 25, 2026
fff299f
chore(ci): ensure Magento writable directories exist
Jun 25, 2026
a1908be
chore(ci): ensure Magento writable directories exist
Jun 25, 2026
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
7 changes: 7 additions & 0 deletions .github/workflows/_internal-check-store.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,19 @@ jobs:
env:
COMPOSER_AUTH: ${{ secrets.COMPOSER_AUTH }}

- name: Opt in to e2e-test
working-directory: ${{ steps.setup-magento.outputs.path }}
run: |
mkdir -p .github
echo '{ "jobs": { "e2e-test": true } }' > .github/check-store.json

- uses: actions/upload-artifact@v7
with:
name: store-fixture-${{ matrix.version }}
path: |
${{ steps.setup-magento.outputs.path }}
!${{ steps.setup-magento.outputs.path }}/vendor
include-hidden-files: true
retention-days: 3

check-store:
Expand Down
160 changes: 158 additions & 2 deletions .github/workflows/check-store.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ jobs:
kind: custom
custom_versions: ${{ steps.get-magento-version.outputs.project }}:${{ fromJSON(steps.get-magento-version.outputs.version) }}

- uses: graycoreio/github-actions-magento2/resolve-check-config@main
## TODO: restore to graycoreio/github-actions-magento2/resolve-check-config@main before merge
- uses: digitalrisedorset/github-actions-magento2/resolve-check-config@feat/check-store-e2e-support
id: resolve
with:
kind: store
matrix: ${{ steps.supported-version.outputs.matrix }}
config_path: ${{ inputs.path }}/.github/check-store.json

unit-test:
runs-on: ${{ matrix.os }}
Expand Down Expand Up @@ -246,4 +248,158 @@ jobs:
- uses: graycoreio/github-actions-magento2/smoke-test@main
if: contains(fromJSON(needs.compute_matrix.outputs.resolved)['smoke-test'].probes, 'graphql')
with:
kind: graphql
kind: graphql

e2e-test:
runs-on: ${{ matrix.os }}
needs: compute_matrix
if: ${{ fromJSON(needs.compute_matrix.outputs.resolved)['e2e-test'].enabled != false }}
services: ${{ matrix.services }}
strategy:
matrix: ${{ fromJSON(needs.compute_matrix.outputs.resolved)['e2e-test'].matrix }}

steps:
- uses: actions/checkout@v6
if: inputs.store_artifact_name == ''

- uses: actions/download-artifact@v8
if: inputs.store_artifact_name != ''
with:
name: ${{ inputs.store_artifact_name }}
path: ${{ inputs.path }}

- uses: graycoreio/github-actions-magento2/setup-magento@main
id: setup-magento
with:
php-version: ${{ matrix.php }}
tools: composer:v${{ matrix.composer }}
mode: store
working-directory: ${{ inputs.path }}
composer_auth: ${{ secrets.composer_auth }}

- name: Detect E2E npm contract
Comment thread
damienwebdev marked this conversation as resolved.
id: detect-e2e
working-directory: ${{ steps.setup-magento.outputs.path }}
run: |
if [ -d dev/tests/e2e ] \
&& [ "$(find dev/tests/e2e -type f | wc -l)" -gt 0 ] \
&& [ -f package.json ]; then
echo "enabled=true" >> "$GITHUB_OUTPUT"
else
echo "enabled=false" >> "$GITHUB_OUTPUT"
echo "::notice::No package.json found, skipping E2E"
fi

- uses: graycoreio/github-actions-magento2/cache-magento@main
with:
composer_cache_key: ${{ inputs.composer_cache_key }}
working-directory: ${{ steps.setup-magento.outputs.path }}
stamp: ${{ inputs.stamp }}

- name: Composer install
working-directory: ${{ steps.setup-magento.outputs.path }}
run: composer install
env:
COMPOSER_AUTH: ${{ secrets.composer_auth }}

- uses: graycoreio/github-actions-magento2/setup-install@main
id: setup-install
with:
services: ${{ toJSON(matrix.services) }}
path: ${{ steps.setup-magento.outputs.path }}
container_id: ${{ job.services['php-fpm'].id }}
extra_args: --magento-init-params=MAGE_MODE=developer

- uses: graycoreio/github-actions-magento2/configure-service-nginx@main
with:
container_id: ${{ job.services.nginx.id }}
magento_path: ${{ inputs.path }}

- uses: actions/setup-node@v4
Comment thread
damienwebdev marked this conversation as resolved.
with:
node-version: 24

- name: Prepare Magento writable directories
working-directory: ${{ steps.setup-magento.outputs.path }}
run: |
mkdir -p var generated pub/static pub/media

chmod -R u+rwX,g+rwX \
var \
generated \
pub/static \
pub/media

chmod +x bin/magento

Comment thread
damienwebdev marked this conversation as resolved.
- name: Install Magento sample data
working-directory: ${{ steps.setup-magento.outputs.path }}
run: |
bin/magento sampledata:deploy
composer update
bin/magento setup:upgrade
bin/magento indexer:reindex

- name: Install MageOS E2E suite
working-directory: ${{ steps.setup-magento.outputs.path }}
run: |
mkdir -p dev/tests

git clone \
--branch ci/tests-e2e-playwright-elgentos-hyva \
https://github.com/digitalrisedorset/mageos-magento2.git \
mageos-elgentos-e2e

mv mageos-elgentos-e2e/dev/tests/e2e dev/tests/
rm -rf mageos-elgentos-e2e

- name: Generate E2E .env
working-directory: ${{ steps.setup-magento.outputs.path }}/dev/tests/e2e
# values below come from setup-install/src/build-command.ts and should be refactored later
run: |
cat > .env <<EOF
PLAYWRIGHT_BASE_URL=http://localhost/
PLAYWRIGHT_PRODUCTION_URL=http://localhost/
PLAYWRIGHT_REVIEW_URL=http://localhost/
MAGENTO_ADMIN_SLUG=admin
MAGENTO_ADMIN_USERNAME=admin
MAGENTO_ADMIN_PASSWORD=admin123
MAGENTO_THEME_LOCALE=en_US
EOF

- name: Run E2E tests
working-directory: ${{ steps.setup-magento.outputs.path }}/dev/tests/e2e
run: |
if [ -f package-lock.json ]; then
npm ci
else
npm install
fi

npx playwright install --with-deps chromium
npx playwright test tests/healthcheck.spec.ts

- name: E2E Healthcheck
working-directory: ${{ steps.setup-magento.outputs.path }}/dev/tests/e2e
run: npx playwright test tests/healthcheck.spec.ts

- name: E2E Home
working-directory: ${{ steps.setup-magento.outputs.path }}/dev/tests/e2e
run: npx playwright test tests/home.spec.ts

- name: E2E Category
working-directory: ${{ steps.setup-magento.outputs.path }}/dev/tests/e2e
run: npx playwright test tests/category.spec.ts

- name: E2E Product
working-directory: ${{ steps.setup-magento.outputs.path }}/dev/tests/e2e
run: npx playwright test tests/product.spec.ts

- name: Upload Playwright artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-artifacts
path: |
${{ steps.setup-magento.outputs.path }}/dev/tests/e2e/playwright-report
${{ steps.setup-magento.outputs.path }}/dev/tests/e2e/test-results
9 changes: 9 additions & 0 deletions _test/demo-package/Test/E2E/ItWorksTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const testItWorks = (): string => {
return "Hello world";
};

if (testItWorks() !== "Hello world") {
Comment thread
damienwebdev marked this conversation as resolved.
process.exit(1);
}

console.log("E2E test passed");
6 changes: 5 additions & 1 deletion resolve-check-config/check-store.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
"properties": {
"unit-test": { "$ref": "#/$defs/jobConfig" },
"coding-standard": { "$ref": "#/$defs/jobConfig" },
"smoke-test": { "$ref": "#/$defs/smokeJobConfig" }
"smoke-test": { "$ref": "#/$defs/smokeJobConfig" },
"e2e-test": {
"$ref": "#/$defs/jobConfig",
"description": "Opt-in: e2e-test does not run unless enabled here."
}
},
"additionalProperties": false
}
Expand Down
87 changes: 51 additions & 36 deletions resolve-check-config/dist/index.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions resolve-check-config/examples/check-store.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"jobs": {
"unit-test": true,
"coding-standard": true,
"e2e-test": true,
"integration-test": {
"services": ["search", "queue", "cache"]
},
Expand Down
29 changes: 27 additions & 2 deletions resolve-check-config/src/kinds/store.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const MATRIX: Matrix = {

describe('STORE_JOBS', () => {
it('declares the check-store jobs', () => {
expect(Object.keys(STORE_JOBS).sort()).toEqual(['coding-standard', 'smoke-test', 'unit-test']);
expect(Object.keys(STORE_JOBS).sort()).toEqual(['coding-standard', 'e2e-test', 'smoke-test', 'unit-test']);
});

it('declares smoke-test required tiers (end-user cannot toggle)', () => {
Expand All @@ -35,6 +35,16 @@ describe('STORE_JOBS', () => {
expect(STORE_JOBS['smoke-test'].probes).toEqual(['page']);
});

it('declares e2e-test required tiers (end-user cannot toggle)', () => {
expect(STORE_JOBS['e2e-test'].services).toEqual([]);
expect([...STORE_JOBS['e2e-test'].requiredServices!].sort()).toEqual([
'cache',
'db',
'search',
'web',
]);
});

it('exposes empty service defaults for unit-test and coding-standard', () => {
expect(STORE_JOBS['unit-test'].services).toEqual([]);
expect(STORE_JOBS['coding-standard'].services).toEqual([]);
Expand All @@ -48,7 +58,7 @@ describe('STORE_JOBS', () => {
describe('resolveStoreConfig', () => {
it('emits every known job with default tier expansion, always including mysql for smoke-test', () => {
const resolved = resolveStoreConfig({}, MATRIX);
expect(Object.keys(resolved).sort()).toEqual(['coding-standard', 'smoke-test', 'unit-test']);
expect(Object.keys(resolved).sort()).toEqual(['coding-standard', 'e2e-test', 'smoke-test', 'unit-test']);
expect(resolved['unit-test'].matrix.include[0].services).toEqual({});
expect(Object.keys(resolved['smoke-test'].matrix.include[0].services!).sort()).toEqual([
'mysql',
Expand All @@ -75,6 +85,21 @@ describe('resolveStoreConfig', () => {
]);
});

it('disables e2e-test by default (opt-in job)', () => {
const resolved = resolveStoreConfig({}, MATRIX);
expect(resolved['e2e-test'].enabled).toBe(false);
expect(resolved['unit-test'].enabled).toBe(true);
expect(resolved['smoke-test'].enabled).toBe(true);
});

it('enables e2e-test when the caller opts in', () => {
const resolved = resolveStoreConfig(
{ jobs: { 'e2e-test': true } },
MATRIX,
);
expect(resolved['e2e-test'].enabled).toBe(true);
});

it('honors enabled=false for a job', () => {
const resolved = resolveStoreConfig(
{ jobs: { 'smoke-test': false } },
Expand Down
5 changes: 5 additions & 0 deletions resolve-check-config/src/kinds/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export const STORE_JOBS: Record<string, JobDefaults> = {
requiredServices: ['db', 'search', 'queue', 'cache', 'web'],
probes: ['page'],
},
'e2e-test': {
services: [],
requiredServices: ['db', 'search', 'cache', 'web'],
enabledByDefault: false,
},
};

export const KNOWN_JOBS_STORE: readonly string[] = Object.keys(STORE_JOBS);
Expand Down
2 changes: 1 addition & 1 deletion resolve-check-config/src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const normalizeJobEntry = (
defaults: JobDefaults,
): { enabled: boolean; tiers: readonly Tier[]; probes?: readonly Probe[] } => {
if (raw === undefined) {
return { enabled: true, tiers: defaults.services, probes: defaults.probes };
return { enabled: defaults.enabledByDefault ?? true, tiers: defaults.services, probes: defaults.probes };
}
if (typeof raw === 'boolean') {
return { enabled: raw, tiers: defaults.services, probes: defaults.probes };
Expand Down
4 changes: 4 additions & 0 deletions resolve-check-config/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,15 @@ export interface Matrix {
* `probes` is the default smoke-test probe list used when the caller
* does not override it. Only jobs that declare it support the
* `probes` config key; omit it for jobs that have no probe concept.
* `enabledByDefault` controls the `enabled` value emitted when the
* caller's config omits the job entirely. Defaults to `true`; set
* `false` for opt-in jobs.
*/
export interface JobDefaults {
services: readonly Tier[];
requiredServices?: readonly Tier[];
probes?: readonly Probe[];
enabledByDefault?: boolean;
}

/**
Expand Down