Skip to content

chore(tests): fix playwright e2e tests#298

Merged
kmendell merged 7 commits into1.0.0from
refactor/fix-tests
Jun 12, 2025
Merged

chore(tests): fix playwright e2e tests#298
kmendell merged 7 commits into1.0.0from
refactor/fix-tests

Conversation

@kmendell
Copy link
Copy Markdown
Member

@kmendell kmendell commented Jun 12, 2025

Summary by CodeRabbit

  • New Features

    • Added a new Docker Compose configuration for testing environments.
    • Introduced dedicated test dependencies and TypeScript configuration for the test suite.
  • Bug Fixes

    • Improved Playwright E2E workflow reliability with enhanced caching, Docker handling, and updated test execution paths.
  • Refactor

    • Migrated Playwright test setup and all test files to a new directory structure.
    • Updated Playwright configuration for new test locations and Docker-based web server startup.
  • Style

    • Reformatted code and imports for consistent style and readability.
    • Updated Prettier configuration for formatting preferences.
  • Tests

    • Rewrote and reorganized end-to-end test suites for converter, images, and volumes features, improving coverage and maintainability.
  • Chores

    • Updated .gitignore rules to better target test-related data files.

@getarcaneapp getarcaneapp deleted a comment from coderabbitai bot Jun 12, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jun 12, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

This change restructures the Playwright end-to-end (E2E) test setup by moving test files into a new directory structure, updating configuration and workflow files, and adding a dedicated Docker Compose file for testing. It deletes old test files, introduces new or refactored test suites, and adjusts project settings, caching, and ignore rules to match the new organization.

Changes

File(s) Change Summary
.github/workflows/e2e-tests.yml Updated Playwright E2E workflow: improved caching, made Docker volume creation idempotent, added Docker image pull, changed dependency and test execution paths, updated report handling, and fixed minor typos.
.gitignore Refined ignore rules to target test artifacts under tests/, removing broader top-level ignores.
docker-compose.test.yml Added new Docker Compose file defining an arcane service with build, ports, volumes, environment, and restart policy for test runs.
frontend/.prettierrc Increased printWidth, removed Tailwind CSS plugin, reformatted overrides for clarity.
frontend/src/routes/+layout.svelte Reformatted code: switched to double quotes, adjusted indentation, removed richColors prop from <Toaster>, no logic changes.
tests/.auth/login.json Updated authentication state: replaced kit.session cookie with JWT token, updated expiration, added new localStorage entry.
tests/auth.setup.ts Deleted: Playwright authentication setup script moved to new location.
tests/converter.spec.ts Deleted: Old Playwright test suite for Docker Run to Compose Converter replaced by new version.
tests/images.spec.ts Deleted: Old Playwright test suite for Images page replaced by new version.
tests/volumes.spec.ts Deleted: Old Playwright test suite for Volumes page replaced by new version.
tests/package.json
tests/tsconfig.json
Added: New package and TypeScript configuration files for the tests directory, specifying Playwright and Node types.
tests/playwright.config.ts Updated Playwright config: changed test and output directories, updated reporter/output, restructured projects and test match patterns, switched web server command to Docker Compose.
tests/setup/auth.setup.ts Added: New Playwright authentication setup script under setup/ directory, functionally similar to deleted script.
tests/spec/converter.spec.ts Added: New/refactored Playwright test suite for Docker Run to Compose Converter, with updated structure and test coverage.
tests/spec/images.spec.ts Added: New/refactored Playwright test suite for Images page, with improved helper functions and test coverage.
tests/spec/volumes.spec.ts Added: New/refactored Playwright test suite for Volumes page, including helper functions, state handling, and UI/API tests.

Possibly related PRs

  • ofkm/arcane#96: Refactors API service classes, replaces form actions with API routes, and adds E2E tests for containers, stacks, volumes, networks, and images—directly related to this PR's restructuring and expansion of E2E test coverage and test organization.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@kmendell kmendell marked this pull request as ready for review June 12, 2025 16:35
@kmendell
Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jun 12, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (9)
tests/tsconfig.json (1)

1-6: Improve TypeScript compiler configuration for tests

Consider enhancing the tsconfig.json with stricter type checking and proper module resolution, and by including necessary type definitions for Playwright. For example:

  "compilerOptions": {
    "baseUrl": ".",
    "lib": ["ES2022"],
+   "strict": true,
+   "moduleResolution": "node",
+   "types": ["node", "@playwright/test"]
  }
tests/package.json (1)

1-7: Add a convenience script for running tests

To simplify test execution, add a "scripts" section:

 {
   "type": "module",
   "devDependencies": {
     "@playwright/test": "^1.52.0",
     "@types/node": "^22.15.21"
   },
+  "scripts": {
+    "test": "playwright test"
+  }
 }
.gitignore (1)

33-36: Refine ignore patterns for test artifacts

Use anchored and recursive patterns to ensure complete coverage of test outputs:

- #tests data
- tests/test-results/*
- tests/.report/*
- tests/.auth/*
+ # Playwright test artifacts
+ /tests/test-results/**
+ /tests/.report/**
+ /tests/.auth/**
docker-compose.test.yml (1)

1-9: Add healthcheck to ensure service readiness before tests

Integrate a health check so Playwright waits for the app to be up:

services:
  arcane:
    # ...
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 5s
      timeout: 2s
      retries: 5
tests/spec/converter.spec.ts (1)

18-21: Replace magic sleeps with deterministic waits

waitForTimeout(300) introduces flakiness and slows CI.
Wait for the section to expand, e.g.:

await page.getByRole('region', { name: /Converter/i }).waitFor({ state: 'visible' });

Apply the same pattern in the four places above.

Also applies to: 60-62, 100-102, 116-118

tests/spec/volumes.spec.ts (1)

98-98: Prefer regex literal

-    await expect(page).toHaveURL(new RegExp(`/volumes/.+`));
+    await expect(page).toHaveURL(/\/volumes\/.+/);

Avoid the RegExp constructor for readability and minor perf.

🧰 Tools
🪛 Biome (1.9.4)

[error] 98-98: Use a regular expression literal instead of the RegExp constructor.

Regular expression literals avoid some escaping required in a string literal, and are easier to analyze statically.
Safe fix: Use a literal notation instead.

(lint/complexity/useRegexLiterals)

tests/spec/images.spec.ts (3)

21-33: page.goto is executed twice per test – drop the duplicate calls

beforeEach already performs page.goto('/images').
Repeating page.goto('/images') at the top of every test adds ~200-300 ms per test and slightly increases flake risk. Consider removing the per-test goto and only rely on the beforeEach navigation.


32-33: Replace console.log with Playwright’s built-in logging

Use test.info().log() so messages are scoped to the test and show up only when a test fails or when --output is requested.

-  console.log(`Found ${realImages.length} real images for testing`);
+  test.info().log(`Found ${realImages.length} real images for testing`);

155-166: Avoid duplicated string literals for image name

The same image reference appears multiple times in this file. Extract it to a constant to ensure consistency when it inevitably changes.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a65f537 and bb53337.

⛔ Files ignored due to path filters (1)
  • tests/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (17)
  • .github/workflows/e2e-tests.yml (1 hunks)
  • .gitignore (1 hunks)
  • docker-compose.test.yml (1 hunks)
  • frontend/.prettierrc (1 hunks)
  • frontend/src/routes/+layout.svelte (1 hunks)
  • tests/.auth/login.json (2 hunks)
  • tests/auth.setup.ts (0 hunks)
  • tests/converter.spec.ts (0 hunks)
  • tests/images.spec.ts (0 hunks)
  • tests/package.json (1 hunks)
  • tests/playwright.config.ts (1 hunks)
  • tests/setup/auth.setup.ts (1 hunks)
  • tests/spec/converter.spec.ts (1 hunks)
  • tests/spec/images.spec.ts (1 hunks)
  • tests/spec/volumes.spec.ts (1 hunks)
  • tests/tsconfig.json (1 hunks)
  • tests/volumes.spec.ts (0 hunks)
💤 Files with no reviewable changes (4)
  • tests/auth.setup.ts
  • tests/converter.spec.ts
  • tests/volumes.spec.ts
  • tests/images.spec.ts
🧰 Additional context used
🪛 Gitleaks (8.26.0)
tests/.auth/login.json

5-5: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)

🪛 Biome (1.9.4)
tests/spec/volumes.spec.ts

[error] 98-98: Use a regular expression literal instead of the RegExp constructor.

Regular expression literals avoid some escaping required in a string literal, and are easier to analyze statically.
Safe fix: Use a literal notation instead.

(lint/complexity/useRegexLiterals)

🔇 Additional comments (7)
frontend/.prettierrc (2)

2-6: Verify Prettier configuration updates.
The increased printWidth and removal of the Tailwind CSS plugin can significantly alter formatting. Ensure these changes are intentional and that dropping prettier-plugin-tailwindcss won’t break class ordering for your Tailwind-based styles.


7-14: Prettier overrides look good.
The multi-line override for *.svelte with the svelte parser is clear and aligns with plugin usage.

frontend/src/routes/+layout.svelte (2)

2-74: Skip formatting-only changes.
All modifications in these ranges are stylistic (indentation, quote style) without any behavioral changes.

Also applies to: 76-106


75-75: Verify removal of richColors prop from <Toaster />.
Confirm that the default color settings still meet UX requirements and that no test assertions rely on the removed richColors prop.

tests/.auth/login.json (1)

23-28: Verify new localStorage entry is covered by tests

You’ve added "collapsible-cards-expanded" to the auth state. Ensure existing tests expect and validate this key where necessary.

tests/playwright.config.ts (1)

3-4: Ensure .auth exists before tests run

storageState: authFile assumes .auth/login.json can be written/read.
Confirm the directory is created in the setup script (see earlier comment) or add a pre-test hook here.

tests/spec/images.spec.ts (1)

84-103: Pull-image test skips on realImages but hard-codes an image name

If there are zero images, the test is skipped, yet the locator later relies on the presence of ghcr.io/linuxserver/nginx in the table – unrelated to realImages. Either:

  1. Look up the first row from realImages instead of the hard-coded string, or
  2. Remove the realImages.length guard and rely solely on the hard-coded locator.

Clarify the intent to avoid silent false negatives.

Comment on lines +13 to +18
- PUID=1000
- PGID=1000
- DATABASE_URL=sqlite:///app/data/arcane.db
- ENCRYPTION_KEY=3JDIgolks2tJ9ymm1AdqzlYMWu0DUWyt
- JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
- APP_ENV=TEST
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid hardcoding secrets in test configuration

Hardcoded encryption keys and JWT secrets introduce security risk, even in test environments. Inject them via environment variables instead:

     environment:
-      - ENCRYPTION_KEY=3JDIgolks2tJ9ymm1AdqzlYMWu0DUWyt
-      - JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
+      - ENCRYPTION_KEY=${ENCRYPTION_KEY}
+      - JWT_SECRET=${JWT_SECRET}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- PUID=1000
- PGID=1000
- DATABASE_URL=sqlite:///app/data/arcane.db
- ENCRYPTION_KEY=3JDIgolks2tJ9ymm1AdqzlYMWu0DUWyt
- JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
- APP_ENV=TEST
- PUID=1000
- PGID=1000
- DATABASE_URL=sqlite:///app/data/arcane.db
- - ENCRYPTION_KEY=3JDIgolks2tJ9ymm1AdqzlYMWu0DUWyt
- - JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
+ - ENCRYPTION_KEY=${ENCRYPTION_KEY}
+ - JWT_SECRET=${JWT_SECRET}
- APP_ENV=TEST
🤖 Prompt for AI Agents
In docker-compose.test.yml around lines 13 to 18, the encryption key and JWT
secret are hardcoded, which poses a security risk. Remove the hardcoded values
for ENCRYPTION_KEY and JWT_SECRET and modify the configuration to read these
values from environment variables instead, allowing secure injection of secrets
during test runs.

Comment on lines +111 to +113
const deleteableImage = realImages.find((img) => !img.inUse);
test.skip(deleteableImage, 'No deletable images available');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Incorrect test.skip condition prevents the test from ever running

test.skip expects a boolean. Passing the object itself will always evaluate as truthy and skip even when a deletable image exists.

-    const deleteableImage = realImages.find((img) => !img.inUse);
-    test.skip(deleteableImage, 'No deletable images available');
+    const deleteableImage = realImages.find((img) => !img.inUse);
+    test.skip(!deleteableImage, 'No deletable images available');
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const deleteableImage = realImages.find((img) => !img.inUse);
test.skip(deleteableImage, 'No deletable images available');
const deleteableImage = realImages.find((img) => !img.inUse);
test.skip(!deleteableImage, 'No deletable images available');
🤖 Prompt for AI Agents
In tests/spec/images.spec.ts around lines 111 to 113, the test.skip call
incorrectly passes an object instead of a boolean, causing the test to always
skip. Change the condition to pass a boolean by negating the existence of
deleteableImage, so the test only skips when no deletable images are available.

Comment on lines +3 to +17
async function fetchImagesWithRetry(page: Page, maxRetries = 3): Promise<any[]> {
let retries = 0;
while (retries < maxRetries) {
try {
const response = await page.request.get('/api/images');
const images = await response.json();
return images.data;
} catch (error) {
retries++;
if (retries >= maxRetries) throw error;
await new Promise((resolve) => setTimeout(resolve, 1000));
}
}
return [];
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Harden fetchImagesWithRetry against non-200 responses and malformed JSON

response.json() will throw when the server returns non-JSON or a non-2xx status code, causing an early, unrecoverable failure that the retry loop never catches. Add an explicit status check and safeguard the JSON parsing.

-      const response = await page.request.get('/api/images');
-      const images = await response.json();
-      return images.data;
+      const response = await page.request.get('/api/images');
+      if (!response.ok()) {
+        throw new Error(`GET /api/images returned ${response.status()}`);
+      }
+      const body = await response.json().catch(() => ({}));
+      return Array.isArray(body.data) ? body.data : [];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async function fetchImagesWithRetry(page: Page, maxRetries = 3): Promise<any[]> {
let retries = 0;
while (retries < maxRetries) {
try {
const response = await page.request.get('/api/images');
const images = await response.json();
return images.data;
} catch (error) {
retries++;
if (retries >= maxRetries) throw error;
await new Promise((resolve) => setTimeout(resolve, 1000));
}
}
return [];
}
async function fetchImagesWithRetry(page: Page, maxRetries = 3): Promise<any[]> {
let retries = 0;
while (retries < maxRetries) {
try {
const response = await page.request.get('/api/images');
if (!response.ok()) {
throw new Error(`GET /api/images returned ${response.status()}`);
}
const body = await response.json().catch(() => ({}));
return Array.isArray(body.data) ? body.data : [];
} catch (error) {
retries++;
if (retries >= maxRetries) throw error;
await new Promise((resolve) => setTimeout(resolve, 1000));
}
}
return [];
}
🤖 Prompt for AI Agents
In tests/spec/images.spec.ts around lines 3 to 17, the fetchImagesWithRetry
function does not handle non-200 HTTP responses or malformed JSON, causing
unhandled exceptions that bypass retries. Modify the function to first check if
the response status is 200 before attempting to parse JSON, and wrap the JSON
parsing in a try-catch block to handle parsing errors gracefully, allowing the
retry logic to proceed correctly.

@kmendell kmendell merged commit f132448 into 1.0.0 Jun 12, 2025
1 check passed
@kmendell kmendell deleted the refactor/fix-tests branch June 12, 2025 17:18
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.

1 participant