Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
98 changes: 64 additions & 34 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ on:
urls:
description: "urls"
required: true

pr_number:
description: "Pull Request number"
required: true
jobs:
e2e_tests:
name: E2E Tests
Expand All @@ -31,12 +33,23 @@ jobs:
- name: Save E2E URLs
working-directory: examples/e2e
run: |
echo "${{ inputs.urls }}" | base64 -d > urls.json
echo "${{ inputs.urls }}" | base64 -d > app-configs.json

- name: Print E2E URLs
working-directory: examples/e2e
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 8

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "22"

- name: Install Dependencies
working-directory: ./examples/e2e
run: |
cat urls.json
pnpm install
pnpm exec playwright install --with-deps

- name: Create Status Check
uses: actions/github-script@v6
Expand All @@ -51,33 +64,50 @@ jobs:
started_at: new Date().toISOString()
})

# - name: Run Tests
# id: run_tests
# run: |
# cat tests/.env.test
# echo "Running E2E tests..."
# # Your actual test commands here
- name: Print app configs
working-directory: examples/e2e
run: |
cat app-configs.json

- name: Run Tests
id: run_tests
working-directory: ./examples/e2e
continue-on-error: true
run: |
pnpm playwright test

- name: Wait 1 minute
run: sleep 60

# - name: Update Status Check
# if: always()
# uses: actions/github-script@v6
# with:
# script: |
# const conclusion = '${{ steps.run_tests.outcome }}' === 'success' ? 'success' : 'failure';
# await github.rest.checks.create({
# owner: context.repo.owner,
# repo: context.repo.repo,
# name: 'E2E Tests',
# head_sha: '${{ github.event.client_payload.sha }}',
# status: 'completed',
# conclusion: conclusion,
# completed_at: new Date().toISOString(),
# output: {
# title: conclusion === 'success' ? 'E2E Tests Passed' : 'E2E Tests Failed',
# summary: conclusion === 'success' ? 'All tests passed successfully' : 'Some tests failed'
# }
# });

- name: Comment post-deployment
uses: thollander/actions-comment-pull-request@v3
with:
pr-number: ${{ inputs.pr_number }}
comment-tag: test-run-status-update
file-path: ./examples/e2e/test-results/test-run-comment.md

- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: |
examples/e2e/playwright-report/
examples/e2e/test-results/
retention-days: 30

- name: Update Status Check
if: always()
uses: actions/github-script@v6
with:
script: |
const conclusion = '${{ steps.run_tests.outcome }}' === 'success' ? 'success' : 'failure';
await github.rest.checks.create({
owner: context.repo.owner,
repo: context.repo.repo,
name: 'E2E Tests',
head_sha: '${{ inputs.sha }}',
status: 'completed',
conclusion: conclusion,
completed_at: new Date().toISOString(),
output: {
title: conclusion === 'success' ? 'E2E Tests Passed' : 'E2E Tests Failed',
summary: conclusion === 'success' ? 'All tests passed successfully' : 'Some tests failed'
}
});
36 changes: 24 additions & 12 deletions .github/workflows/preview-envs-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,28 @@ jobs:
strategy:
matrix:
app:
- { project: "coagents-research-canvas", type: "agent", deps: "remote-deps" }
- { project: "coagents-research-canvas", type: "agent", deps: "local-deps" }
- {
project: "coagents-research-canvas",
type: "agent",
deps: "remote-deps",
}
- {
project: "coagents-research-canvas",
type: "agent",
deps: "local-deps",
}
- { project: "coagents-research-canvas", type: "ui" }
- { project: "coagents-routing", type: "agent", deps: "remote-deps" }
- { project: "coagents-routing", type: "agent", deps: "local-deps" }
- { project: "coagents-routing", type: "ui" }
- { project: "coagents-qa-text", type: "agent", deps: "remote-deps" }
- { project: "coagents-qa-text", type: "agent", deps: "local-deps" }
- { project: "coagents-qa-text", type: "ui" }
- { project: "coagents-qa-native", type: "agent", deps: "remote-deps" }
- {
project: "coagents-qa-native",
type: "agent",
deps: "remote-deps",
}
- { project: "coagents-qa-native", type: "agent", deps: "local-deps" }
- { project: "coagents-qa-native", type: "ui" }
steps:
Expand All @@ -51,7 +63,7 @@ jobs:
- name: AWS ECR Login
run: |
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 058264219587.dkr.ecr.us-east-1.amazonaws.com

- name: (UI) Setup pnpm
if: matrix.app.type == 'ui'
uses: pnpm/action-setup@v4
Expand All @@ -63,8 +75,8 @@ jobs:
uses: actions/setup-node@v2
with:
node-version: 21.x
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
cache: "pnpm"
cache-dependency-path: "**/pnpm-lock.yaml"

- name: (UI) Install dependencies
if: matrix.app.type == 'ui'
Expand Down Expand Up @@ -147,8 +159,8 @@ jobs:
uses: actions/setup-node@v2
with:
node-version: 21.x
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
cache: "pnpm"
cache-dependency-path: "**/pnpm-lock.yaml"

- name: Infra install dependencies
working-directory: infra
Expand All @@ -174,10 +186,10 @@ jobs:
working-directory: ./infra
run: cdk deploy --profile default --all --require-approval never --outputs-file=cdk_outputs.json --concurrency 10
env:
UNIQUE_ENV_ID: 'PR${{ github.event.number }}'
UNIQUE_ENV_ID: "PR${{ github.event.number }}"
GITHUB_ACTIONS_RUN_ID: "${{ github.run_id }}"
GITHUB_PR_NUMBER: "${{ github.event.number }}"

- name: Generate table from outputs
id: generate-table
working-directory: infra
Expand Down Expand Up @@ -207,11 +219,11 @@ jobs:
working-directory: infra
run: |
echo "e2e-urls=$(node get-e2e-tests-urls.js | base64 -w 0)" >> "$GITHUB_OUTPUT"

- name: Trigger E2E Tests
uses: benc-uk/workflow-dispatch@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
workflow: "e2e.yml"
ref: "${{ github.event.pull_request.head.ref }}"
inputs: '{"ref": "${{ github.event.pull_request.head.ref }}", "sha": "${{ github.event.pull_request.head.sha }}", "urls": "${{ steps.export-e2e-urls.outputs.e2e-urls }}"}'
inputs: '{"ref": "${{ github.event.pull_request.head.ref }}", "sha": "${{ github.event.pull_request.head.sha }}", "urls": "${{ steps.export-e2e-urls.outputs.e2e-urls }}", "pr_number": "${{ github.event.pull_request.number }}"}'
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ __snapshots__
node_modules
.idea/
cdk_outputs.json
.turbo
.turbo
test-run-comment.md
1 change: 1 addition & 0 deletions examples/e2e/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ node_modules/
/playwright-report/
/blob-report/
/playwright/.cache/
app-configs.json
67 changes: 67 additions & 0 deletions examples/e2e/lib/config-helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// lib/config-helper.ts
import configs from "../app-configs.json";

// Project name constants with type safety
export const PROJECT_NAMES = {
AI_RESEARCHER: "coagents-ai-researcher",
QA_NATIVE: "coagents-qa-native",
QA_TEXT: "coagents-qa-text",
RESEARCH_CANVAS: "coagents-research-canvas",
} as const;

export type ProjectName = (typeof PROJECT_NAMES)[keyof typeof PROJECT_NAMES];

export interface ConfigItem {
url: string;
description: string;
projectName: ProjectName;
}

export interface ConfigMap {
[key: string]: ConfigItem;
}

/**
* Returns raw config map
*/
export const getConfigs = (): ConfigMap => {
return configs as ConfigMap;
};

/**
* Groups configuration items by project name and description
*/
export const groupConfigsByDescription = (
configs: ConfigMap
): Record<ProjectName, Record<string, ConfigItem[]>> => {
return Object.entries(configs).reduce((acc, [key, value]) => {
const { projectName, description } = value;

if (!acc[projectName]) {
acc[projectName] = {};
}

if (!acc[projectName][description]) {
acc[projectName][description] = [];
}

acc[projectName][description].push({ ...value, key });

return acc;
}, {} as Record<ProjectName, Record<string, ConfigItem[]>>);
};

/**
* Filter configs by project name
*/
export const filterConfigsByProject = (
configs: ConfigMap,
projectName: ProjectName
): ConfigMap => {
return Object.entries(configs).reduce((acc, [key, value]) => {
if (value.projectName === projectName) {
acc[key] = value;
}
return acc;
}, {} as ConfigMap);
};
3 changes: 2 additions & 1 deletion examples/e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"license": "ISC",
"devDependencies": {
"@playwright/test": "^1.48.2",
"@types/node": "^22.8.4"
"@types/node": "^22.8.4",
"json2md": "^2.0.1"
}
}
50 changes: 13 additions & 37 deletions examples/e2e/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineConfig, devices } from '@playwright/test';
import { defineConfig, devices } from "@playwright/test";

/**
* Read environment variables from file.
Expand All @@ -12,8 +12,7 @@ import { defineConfig, devices } from '@playwright/test';
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
timeout: 340000,
testDir: './tests',
testDir: "./tests",
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
Expand All @@ -23,52 +22,29 @@ export default defineConfig({
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
reporter: [
[
"./reporters/structured-reporter.ts",
{
outputFile: "test-results/test-run-comment.md",
},
],
],
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
// baseURL: 'http://127.0.0.1:3000',

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
trace: "on-first-retry",
},

/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
name: "chromium",
use: { ...devices["Desktop Chrome"] },
},

{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},

{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},

/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: { ...devices['Pixel 5'] },
// },
// {
// name: 'Mobile Safari',
// use: { ...devices['iPhone 12'] },
// },

/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
],

/* Run your local dev server before starting the tests */
Expand Down
Loading