Skip to content
Draft
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
101 changes: 99 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,99 @@ 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
if: steps.detect-e2e.outputs.enabled == 'true'
with:
container_id: ${{ job.services.nginx.id }}
magento_path: ${{ inputs.path }}

- uses: actions/setup-node@v4
Comment thread
damienwebdev marked this conversation as resolved.
if: steps.detect-e2e.outputs.enabled == 'true'
with:
cache: npm

Comment thread
damienwebdev marked this conversation as resolved.
- name: Install Magento sample data
if: steps.detect-e2e.outputs.enabled == 'true'
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 \
dev/tests/e2e

- name: Run E2E tests
working-directory: ${{ steps.setup-magento.outputs.path }}/dev/tests/e2e
run: |
npm ci
npx playwright test
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
Loading