Skip to content

Conversation

@alimahboubi
Copy link
Contributor

What does this PR do?

This pull request introduces a new module to the Testcontainers for .NET library, enabling support for Playwright-based browser testing within Docker containers. The module allows users to run Playwright tests in isolated environments, facilitating consistent and reproducible end-to-end testing scenarios.

Why is it important?

Integrating Playwright into Testcontainers for .NET addresses the growing demand for modern, reliable browser automation tools in testing workflows. Playwright offers robust features for cross-browser testing, and its inclusion enhances the library's capabilities, providing developers with a comprehensive solution for containerized testing environments.

Related issues

Follow-ups

  • Update the official documentation to include usage guidelines and examples for the Playwright module.

  • Monitor community feedback to identify potential enhancements or issues related to the new module.

Implemented the initial version of the Testcontainers.Playwright library. This includes the PlaywrightBuilder, PlaywrightContainer, PlaywrightConfiguration, PlaywrightBrowser classes, and the project file setup. The changes also integrate the new project into the solution file.
Introduce a new Playwright test project with necessary configurations and dependencies. Implement initial container setup and a test to validate the integration with a sample "hello world" application.
@netlify
Copy link

netlify bot commented Nov 5, 2024

Deploy Preview for testcontainers-dotnet ready!

Name Link
🔨 Latest commit 1a29df6
🔍 Latest deploy log https://app.netlify.com/projects/testcontainers-dotnet/deploys/690d040a56d7c200084cb2d1
😎 Deploy Preview https://deploy-preview-1288--testcontainers-dotnet.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Removed the specific version number from the xunit package reference in the project file. This change allows the project to always use the latest compatible version of xunit.
Removed unnecessary properties and updated package order in the test project file. This cleanup improves readability and aligns the project with current standards, ensuring consistent behavior.
Include System for fundamental classes and base classes, and threading for asynchronous operations. This ensures that the components used in the TestInitializer are properly referenced and compiled.
Move common usings to GlobalUsings.cs for better maintainability and cleaner code in TestInitializer.cs. This enhances code organization and reduces redundancy.
@HofmeisterAn HofmeisterAn added enhancement New feature or request module An official Testcontainers module labels Nov 10, 2024
@HofmeisterAn HofmeisterAn force-pushed the develop branch 3 times, most recently from 4900ecd to 8fa5f1b Compare October 3, 2025 20:17
@coderabbitai
Copy link

coderabbitai bot commented Nov 2, 2025

Summary by CodeRabbit

  • New Features

    • Added Playwright module support enabling browser testing with containerized Playwright instances
    • Includes container builder and configuration APIs for Playwright setup
  • Documentation

    • Added Playwright module documentation with configuration examples and best practices
  • Tests

    • Added test suite validating Playwright container functionality

Walkthrough

This PR introduces a complete Testcontainers.Playwright module, adding containerized Playwright browser support. It includes builder and configuration classes following Testcontainers patterns, a container implementation, end-to-end tests verifying browser automation against containerized applications, and comprehensive module documentation.

Changes

Cohort / File(s) Summary
Package Dependencies
Directory.Packages.props
Added Microsoft.Playwright v1.55.0 package version
Solution Configuration
Testcontainers.sln
Registered new Testcontainers.Playwright and Testcontainers.Playwright.Tests projects with Debug/Release configurations and proper nesting
Core Module Implementation
src/Testcontainers.Playwright/.editorconfig, PlaywrightBuilder.cs, PlaywrightConfiguration.cs, PlaywrightContainer.cs, Testcontainers.Playwright.csproj, Usings.cs
Added PlaywrightBuilder (sealed, extending ContainerBuilder) with Init(), Build(), and Clone() methods; PlaywrightConfiguration (sealed, extending ContainerConfiguration) with immutable constructors; PlaywrightContainer (sealed, extending DockerContainer) with GetConnectionString() and GetNetwork(); project targets net8.0/net9.0/netstandard2.0/2.1; global usings for Docker, Testcontainers, and JetBrains libraries
Test Project Implementation
tests/Testcontainers.Playwright.Tests/.editorconfig, .runs-on, PlaywrightContainerTest.cs, Testcontainers.Playwright.Tests.csproj, Usings.cs
Added abstract PlaywrightContainerTest with IAsyncLifetime managing Playwright and hello-world containers; HeadingElementReturnsHelloWorld test validates end-to-end browser automation; nested PlaywrightDefaultConfiguration test class; project targets net9.0 with xUnit, Microsoft.Playwright, and test infrastructure dependencies; runner image set to ubuntu-24.04
Documentation
docs/modules/index.md, docs/modules/playwright.md, mkdocs.yml
Added Playwright module documentation with setup instructions, lifecycle management, container creation examples, network configuration guidance, and browser selection options (Chromium/Firefox/Edge); integrated into module index and MkDocs navigation

Sequence Diagram

sequenceDiagram
    participant Test as PlaywrightContainerTest
    participant HelloWorld as HelloWorldContainer
    participant Playwright as PlaywrightContainer
    participant Browser as Playwright Browser
    participant Page as Browser Page
    
    Test->>HelloWorld: Build and start
    Test->>Playwright: Build and start (default config)
    Test->>Playwright: InitializeAsync
    activate Playwright
    Note over Playwright: WebSocket at localhost:8080
    deactivate Playwright
    
    Test->>Browser: Launch and connect via WebSocket
    activate Browser
    Test->>Page: Create new page
    Test->>Page: Navigate to HelloWorld URL
    Test->>Page: Query h1 element
    Test->>Page: Get inner text
    Note over Page: Assert: "Hello world"
    Test->>Page: Close
    Test->>Browser: Close
    deactivate Browser
    
    Test->>Playwright: DisposeAsync
    Test->>HelloWorld: Dispose
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Areas requiring attention:

  • PlaywrightBuilder.cs: Validate Init() method configuration chain (image, network, port binding, entrypoint, wait strategy) aligns with Playwright container requirements and follows established builder patterns
  • PlaywrightContainer.cs: Verify GetConnectionString() correctly constructs WebSocket URI for Playwright protocol connectivity
  • PlaywrightContainerTest.cs: Review end-to-end test logic for proper async lifecycle management (IAsyncLifetime), container networking setup, and browser automation assertions
  • Configuration inheritance chain: Confirm PlaywrightConfiguration constructors properly propagate through base ContainerConfiguration across immutable merge patterns
  • Project dependencies: Verify Testcontainers.Playwright.Tests correctly references required projects and test frameworks (xUnit, Microsoft.Playwright)

Poem

🐰 A playwright hops into a container so bright,
With browsers bundled tight, for testing each night,
The builder hops merrily, configuring with care,
While tests verify pages with automated flair,
In networks they gather, headless and bold,
Testcontainers' new stage, a tale to be told! 🎭

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 63.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: Add Playwright module' accurately and concisely describes the main change—introducing a new Playwright module to the library.
Description check ✅ Passed The PR description includes both mandatory sections (What and Why), related issues reference, and follow-ups. All key information is present and well-documented.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@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: 4

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d4c61d1 and fc50cad.

📒 Files selected for processing (15)
  • Directory.Packages.props (1 hunks)
  • Testcontainers.sln (3 hunks)
  • src/Testcontainers.Playwright/.editorconfig (1 hunks)
  • src/Testcontainers.Playwright/PlaywrightBrowser.cs (1 hunks)
  • src/Testcontainers.Playwright/PlaywrightBuilder.cs (1 hunks)
  • src/Testcontainers.Playwright/PlaywrightConfiguration.cs (1 hunks)
  • src/Testcontainers.Playwright/PlaywrightContainer.cs (1 hunks)
  • src/Testcontainers.Playwright/Testcontainers.Playwright.csproj (1 hunks)
  • src/Testcontainers.Playwright/Usings.cs (1 hunks)
  • tests/Testcontainers.Playwright.Tests/.editorconfig (1 hunks)
  • tests/Testcontainers.Playwright.Tests/.runs-on (1 hunks)
  • tests/Testcontainers.Playwright.Tests/GlobalUsings.cs (1 hunks)
  • tests/Testcontainers.Playwright.Tests/PlaywrightContainerTest.cs (1 hunks)
  • tests/Testcontainers.Playwright.Tests/TestInitializer.cs (1 hunks)
  • tests/Testcontainers.Playwright.Tests/Testcontainers.Playwright.Tests.csproj (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (7)
src/Testcontainers.Playwright/PlaywrightConfiguration.cs (3)
src/Testcontainers.Playwright/PlaywrightBuilder.cs (1)
  • PublicAPI (7-98)
src/Testcontainers.Playwright/PlaywrightContainer.cs (1)
  • PublicAPI (4-14)
src/Testcontainers/Builders/BuildConfiguration.cs (1)
  • BuildConfiguration (13-150)
src/Testcontainers.Playwright/Usings.cs (2)
src/Testcontainers/Polyfills/X509Certificate2.cs (1)
  • System (17-52)
src/Testcontainers/Logging.cs (1)
  • Logging (10-302)
tests/Testcontainers.Playwright.Tests/TestInitializer.cs (2)
src/Testcontainers.Playwright/PlaywrightBuilder.cs (10)
  • PlaywrightContainer (34-38)
  • PlaywrightBuilder (16-19)
  • PlaywrightBuilder (25-29)
  • PlaywrightBuilder (41-49)
  • PlaywrightBuilder (51-54)
  • PlaywrightBuilder (61-65)
  • PlaywrightBuilder (72-77)
  • PlaywrightBuilder (82-85)
  • PlaywrightBuilder (88-91)
  • PlaywrightBuilder (94-97)
src/Testcontainers/Configurations/Networks/NetworkDriver.cs (1)
  • NetworkDriver (33-36)
tests/Testcontainers.Playwright.Tests/PlaywrightContainerTest.cs (1)
tests/Testcontainers.Playwright.Tests/TestInitializer.cs (3)
  • TestInitializer (8-74)
  • Task (63-67)
  • Task (69-73)
src/Testcontainers.Playwright/PlaywrightBrowser.cs (2)
src/Testcontainers.Playwright/PlaywrightBuilder.cs (1)
  • PublicAPI (7-98)
src/Testcontainers.Playwright/PlaywrightConfiguration.cs (1)
  • PublicAPI (4-70)
src/Testcontainers.Playwright/PlaywrightContainer.cs (2)
src/Testcontainers.Playwright/PlaywrightBuilder.cs (2)
  • PublicAPI (7-98)
  • PlaywrightContainer (34-38)
src/Testcontainers.Playwright/PlaywrightConfiguration.cs (6)
  • PublicAPI (4-70)
  • PlaywrightConfiguration (11-16)
  • PlaywrightConfiguration (22-26)
  • PlaywrightConfiguration (32-36)
  • PlaywrightConfiguration (42-46)
  • PlaywrightConfiguration (53-57)
src/Testcontainers.Playwright/PlaywrightBuilder.cs (4)
src/Testcontainers.Playwright/PlaywrightConfiguration.cs (6)
  • PublicAPI (4-70)
  • PlaywrightConfiguration (11-16)
  • PlaywrightConfiguration (22-26)
  • PlaywrightConfiguration (32-36)
  • PlaywrightConfiguration (42-46)
  • PlaywrightConfiguration (53-57)
src/Testcontainers.Playwright/PlaywrightContainer.cs (2)
  • PublicAPI (4-14)
  • PlaywrightContainer (11-13)
tests/Testcontainers.Playwright.Tests/TestInitializer.cs (1)
  • PlaywrightContainer (52-61)
src/Testcontainers.Playwright/PlaywrightBrowser.cs (2)
  • PlaywrightBrowser (34-37)
  • PlaywrightBrowser (43-46)
🪛 GitHub Actions: Continuous Integration & Delivery
tests/Testcontainers.Playwright.Tests/PlaywrightContainerTest.cs

[error] 17-17: Test failed: Playwright container test HeadingElementReturnsHelloWorld due to WebSocket error: 428 Precondition Required (Playwright version mismatch between server v1.56 and client v1.55).

🔇 Additional comments (7)
tests/Testcontainers.Playwright.Tests/.runs-on (1)

1-1: LGTM!

The ubuntu-24.04 runner specification is appropriate for Playwright tests.

src/Testcontainers.Playwright/.editorconfig (1)

1-1: LGTM!

Standard editorconfig root marker for the Playwright module.

tests/Testcontainers.Playwright.Tests/.editorconfig (1)

1-1: LGTM!

Standard editorconfig root marker for the test project.

tests/Testcontainers.Playwright.Tests/GlobalUsings.cs (1)

1-3: LGTM!

Standard global usings for an xUnit test project.

src/Testcontainers.Playwright/Testcontainers.Playwright.csproj (1)

1-12: LGTM!

The project configuration is well-structured with appropriate multi-targeting (including .NET Standard 2.0/2.1 for broad compatibility) and standard dependencies.

tests/Testcontainers.Playwright.Tests/Testcontainers.Playwright.Tests.csproj (1)

1-19: LGTM!

Standard test project configuration with appropriate dependencies and targeting .NET 9.0.

src/Testcontainers.Playwright/PlaywrightContainer.cs (1)

1-14: LGTM!

Clean implementation of the PlaywrightContainer with appropriate inheritance, documentation, and public API marking.

Copy link

@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: 1

🧹 Nitpick comments (2)
tests/Testcontainers.Playwright.Tests/PlaywrightContainerTest.cs (1)

48-64: Remove unnecessary ConfigureAwait(true) calls in test code.

Using ConfigureAwait(true) in test code is unnecessary and adds overhead by forcing continuation on the captured synchronization context. In test scenarios, the default behavior (omitting ConfigureAwait entirely) or using ConfigureAwait(false) is preferred.

Apply this diff to remove the unnecessary ConfigureAwait(true) calls:

     // Given
     var playwright = await Microsoft.Playwright.Playwright.CreateAsync()
-        .ConfigureAwait(true);
+        .ConfigureAwait(false);
 
     var browser = await playwright.Chromium.ConnectAsync(_playwrightContainer.GetConnectionString())
-        .ConfigureAwait(true);
+        .ConfigureAwait(false);
 
     var page = await browser.NewPageAsync()
-        .ConfigureAwait(true);
+        .ConfigureAwait(false);
 
     // When
     await page.GotoAsync(_helloWorldBaseAddress.ToString())
-        .ConfigureAwait(true);
+        .ConfigureAwait(false);
 
     var headingElement = await page.QuerySelectorAsync("h1")
-        .ConfigureAwait(true);
+        .ConfigureAwait(false);
 
     var headingElementText = await headingElement!.InnerTextAsync()
-        .ConfigureAwait(true);
+        .ConfigureAwait(false);
src/Testcontainers.Playwright/PlaywrightBuilder.cs (1)

54-62: Consider using string interpolation for the wait strategy.

The initialization logic is sound. However, line 61 uses string concatenation which is less readable than string interpolation.

Apply this diff to improve readability:

-        .WithWaitStrategy(Wait.ForUnixContainer().UntilMessageIsLogged("ws://localhost:" + PlaywrightPort + "/playwright"));
+        .WithWaitStrategy(Wait.ForUnixContainer().UntilMessageIsLogged($"ws://localhost:{PlaywrightPort}/playwright"));

Note: The past review comment about refreshing the wait strategy after port/endpoint changes appears to have been addressed by design—the current implementation keeps the port and endpoint fixed rather than making them configurable.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc50cad and 2534b90.

📒 Files selected for processing (9)
  • Testcontainers.sln (6 hunks)
  • src/Testcontainers.Playwright/PlaywrightBrowser.cs (1 hunks)
  • src/Testcontainers.Playwright/PlaywrightBuilder.cs (1 hunks)
  • src/Testcontainers.Playwright/PlaywrightConfiguration.cs (1 hunks)
  • src/Testcontainers.Playwright/PlaywrightContainer.cs (1 hunks)
  • src/Testcontainers.Playwright/Testcontainers.Playwright.csproj (1 hunks)
  • src/Testcontainers.Playwright/Usings.cs (1 hunks)
  • tests/Testcontainers.Playwright.Tests/PlaywrightContainerTest.cs (1 hunks)
  • tests/Testcontainers.Playwright.Tests/Usings.cs (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • tests/Testcontainers.Playwright.Tests/Usings.cs
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/Testcontainers.Playwright/Testcontainers.Playwright.csproj
  • src/Testcontainers.Playwright/Usings.cs
  • src/Testcontainers.Playwright/PlaywrightContainer.cs
  • src/Testcontainers.Playwright/PlaywrightBrowser.cs
  • src/Testcontainers.Playwright/PlaywrightConfiguration.cs
  • Testcontainers.sln
🧰 Additional context used
🧬 Code graph analysis (2)
src/Testcontainers.Playwright/PlaywrightBuilder.cs (3)
src/Testcontainers.Playwright/PlaywrightConfiguration.cs (6)
  • PublicAPI (4-53)
  • PlaywrightConfiguration (10-12)
  • PlaywrightConfiguration (18-22)
  • PlaywrightConfiguration (28-32)
  • PlaywrightConfiguration (38-42)
  • PlaywrightConfiguration (49-52)
src/Testcontainers.Playwright/PlaywrightContainer.cs (2)
  • PublicAPI (4-36)
  • PlaywrightContainer (13-17)
src/Testcontainers.Playwright/PlaywrightBrowser.cs (2)
  • PlaywrightBrowser (37-40)
  • PlaywrightBrowser (46-49)
tests/Testcontainers.Playwright.Tests/PlaywrightContainerTest.cs (3)
src/Testcontainers/Builders/ContainerBuilder.cs (1)
  • IContainer (54-58)
src/Testcontainers.Playwright/PlaywrightBuilder.cs (8)
  • PlaywrightContainer (47-51)
  • PlaywrightBuilder (14-18)
  • PlaywrightBuilder (24-28)
  • PlaywrightBuilder (41-44)
  • PlaywrightBuilder (54-62)
  • PlaywrightBuilder (65-68)
  • PlaywrightBuilder (71-74)
  • PlaywrightBuilder (77-80)
src/Testcontainers.Playwright/PlaywrightContainer.cs (2)
  • PlaywrightContainer (13-17)
  • GetConnectionString (23-26)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: ci (Testcontainers.Playwright, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers, ubuntu-24.04)
  • GitHub Check: analyze (csharp)
🔇 Additional comments (7)
tests/Testcontainers.Playwright.Tests/PlaywrightContainerTest.cs (2)

11-23: LGTM!

The constructor properly configures the hello-world container with network sharing, port binding, and an appropriate HTTP wait strategy. The network configuration correctly references the Playwright container's network to enable inter-container communication.


25-40: LGTM!

The async lifecycle implementation follows best practices with proper sequencing, disposal order, and appropriate use of ConfigureAwait(false) for infrastructure code. The GC.SuppressFinalize call is correctly placed.

Also applies to: 70-77

src/Testcontainers.Playwright/PlaywrightBuilder.cs (5)

7-9: LGTM!

The constants provide sensible defaults for the Playwright container configuration. Using ushort for the port is appropriate given the valid port range.


14-28: LGTM!

The constructor initialization pattern is appropriate for this immutable builder design. The public constructor delegates to the private constructor and then applies default configuration via Init().


41-44: LGTM!

The WithBrowser method provides a clean abstraction for configuring the Playwright browser by delegating to the base WithImage method.


47-51: LGTM!

The Build method follows the standard builder pattern, validating the configuration before constructing the container instance.


65-80: LGTM!

The Clone and Merge methods correctly implement the immutable builder pattern, ensuring that configuration changes return new builder instances rather than mutating existing ones.

@HofmeisterAn HofmeisterAn changed the title Feature/playwright module feat: Add Playwright module Nov 6, 2025
Copy link

@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: 3

♻️ Duplicate comments (1)
tests/Testcontainers.Playwright.Tests/PlaywrightContainerTest.cs (1)

61-65: Add null check for heading element to prevent NPE.

The code uses the null-forgiving operator (!) on line 64 without verifying that QuerySelectorAsync returned a non-null element. This can cause a NullReferenceException if the element is not found.

Apply this diff:

     var headingElement = await page.QuerySelectorAsync("h1")
-        .ConfigureAwait(true);
+        .ConfigureAwait(false);
 
+    Assert.NotNull(headingElement);
+
-    var headingElementText = await headingElement!.InnerTextAsync()
+    var headingElementText = await headingElement.InnerTextAsync()
-        .ConfigureAwait(true);
+        .ConfigureAwait(false);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2534b90 and e2effe8.

📒 Files selected for processing (5)
  • docs/modules/index.md (1 hunks)
  • docs/modules/playwright.md (1 hunks)
  • mkdocs.yml (1 hunks)
  • tests/Testcontainers.Playwright.Tests/PlaywrightContainerTest.cs (1 hunks)
  • tests/Testcontainers.Playwright.Tests/Testcontainers.Playwright.Tests.csproj (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • docs/modules/playwright.md
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-06T16:36:40.804Z
Learnt from: HofmeisterAn
Repo: testcontainers/testcontainers-dotnet PR: 1288
File: Directory.Packages.props:71-71
Timestamp: 2025-11-06T16:36:40.804Z
Learning: CVE-2025-59288 affects only the NPM playwright/playwright-core packages, not the Microsoft.Playwright NuGet package, even though they share similar browser download mechanisms.

Applied to files:

  • docs/modules/index.md
  • tests/Testcontainers.Playwright.Tests/PlaywrightContainerTest.cs
🧬 Code graph analysis (1)
tests/Testcontainers.Playwright.Tests/PlaywrightContainerTest.cs (3)
src/Testcontainers/Builders/ContainerBuilder.cs (1)
  • IContainer (54-58)
src/Testcontainers.Playwright/PlaywrightContainer.cs (2)
  • PlaywrightContainer (13-17)
  • GetConnectionString (23-26)
src/Testcontainers.Playwright/PlaywrightBuilder.cs (8)
  • PlaywrightContainer (47-51)
  • PlaywrightBuilder (14-18)
  • PlaywrightBuilder (24-28)
  • PlaywrightBuilder (41-44)
  • PlaywrightBuilder (54-62)
  • PlaywrightBuilder (65-68)
  • PlaywrightBuilder (71-74)
  • PlaywrightBuilder (77-80)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: analyze (csharp)
🔇 Additional comments (6)
tests/Testcontainers.Playwright.Tests/PlaywrightContainerTest.cs (5)

3-23: LGTM!

The test class structure and constructor logic are well-designed. The hello-world container is correctly configured to share the Playwright container's network, enabling browser access.


25-32: LGTM!

The initialization sequence correctly starts the Playwright container before the hello-world container, ensuring proper setup order.


34-40: LGTM!

The disposal pattern correctly implements the standard IAsyncDisposable pattern.


72-79: LGTM!

The disposal order correctly reverses the initialization sequence, and ConfigureAwait(false) is appropriate for cleanup operations.


81-88: LGTM!

The nested test configuration class follows the standard pattern for providing test implementations of the abstract base class.

mkdocs.yml (1)

63-63: Navigation entry correctly positioned with proper alphabetical ordering.

The Playwright module navigation entry is properly integrated into the Modules section with correct alphabetical sequence (opensearch → playwright → postgres). Verification confirms the referenced documentation file docs/modules/playwright.md exists and contains substantial content (71 lines).

Copy link

@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: 1

🧹 Nitpick comments (1)
src/Testcontainers.Playwright/PlaywrightBrowser.cs (1)

15-33: Consider using official Microsoft Playwright Docker images per best practices.

Official Microsoft Playwright Docker images are available and recommended for .NET. While the current third-party jacoblincool/playwright images are actively maintained (last updated September 2025, 66 GitHub stars, not archived), the best practices for Testcontainers with Playwright .NET recommend using Microsoft's official images or building your own via Dockerfile.

The current approach with pinned versions (1.55.1) follows best practices for version management. However, consider migrating to official Microsoft images for:

  • Officially supported runtime environment
  • Reduced supply chain dependencies
  • Alignment with documented best practices
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e2effe8 and d7ce6ac.

📒 Files selected for processing (2)
  • docs/modules/playwright.md (1 hunks)
  • src/Testcontainers.Playwright/PlaywrightBrowser.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/modules/playwright.md
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-06T16:36:40.804Z
Learnt from: HofmeisterAn
Repo: testcontainers/testcontainers-dotnet PR: 1288
File: Directory.Packages.props:71-71
Timestamp: 2025-11-06T16:36:40.804Z
Learning: CVE-2025-59288 affects only the NPM playwright/playwright-core packages, not the Microsoft.Playwright NuGet package, even though they share similar browser download mechanisms.

Applied to files:

  • src/Testcontainers.Playwright/PlaywrightBrowser.cs
🧬 Code graph analysis (1)
src/Testcontainers.Playwright/PlaywrightBrowser.cs (3)
src/Testcontainers.Playwright/PlaywrightConfiguration.cs (1)
  • PublicAPI (4-53)
src/Testcontainers.Playwright/PlaywrightBuilder.cs (1)
  • PublicAPI (4-81)
src/Testcontainers.Playwright/PlaywrightContainer.cs (1)
  • PublicAPI (4-36)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: analyze (csharp)
🔇 Additional comments (1)
src/Testcontainers.Playwright/PlaywrightBrowser.cs (1)

1-11: LGTM! Clear documentation.

The namespace declaration and XML documentation are well-structured. The explicit mention of the third-party Docker repository and Playwright version provides good transparency for users of this API.

Copy link

@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: 0

♻️ Duplicate comments (1)
src/Testcontainers.Playwright/PlaywrightBuilder.cs (1)

52-54: Wait strategy never matches Playwright’s actual log output

UntilMessageIsLogged is hard-coded to Listening on ws://localhost:8080/, but the CLI emits hosts like 127.0.0.1, 0.0.0.0, or localhost, sometimes with a trailing /ws. The mismatch means the wait condition never fires and the container hangs on start. Please switch to a regex/pattern that tolerates the host/path variations so the wait condition can succeed.

-            .WithWaitStrategy(Wait.ForUnixContainer().UntilMessageIsLogged("Listening on ws://localhost:8080/"));
+            .WithWaitStrategy(Wait.ForUnixContainer()
+                .UntilMessageIsLogged($@"Listening on ws://.*:{PlaywrightPort}(/ws)?/?"));
🧹 Nitpick comments (1)
docs/modules/playwright.md (1)

39-46: Expand network configuration section with complete example.

The network configuration section is minimal. Consider adding a more complete example showing how to use WithBrowser() together with network configuration, or clarify the relationship between GetNetwork() and container networking setup.

Currently, the example shows creating a new container with the shared network, but doesn't demonstrate the initial network setup on the Playwright container or how to use multiple containers in a test scenario end-to-end.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d7ce6ac and 3d1d913.

📒 Files selected for processing (4)
  • docs/modules/index.md (1 hunks)
  • docs/modules/playwright.md (1 hunks)
  • src/Testcontainers.Playwright/PlaywrightBuilder.cs (1 hunks)
  • src/Testcontainers.Playwright/PlaywrightContainer.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/Testcontainers.Playwright/PlaywrightContainer.cs
  • docs/modules/index.md
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-06T16:36:40.804Z
Learnt from: HofmeisterAn
Repo: testcontainers/testcontainers-dotnet PR: 1288
File: Directory.Packages.props:71-71
Timestamp: 2025-11-06T16:36:40.804Z
Learning: CVE-2025-59288 affects only the NPM playwright/playwright-core packages, not the Microsoft.Playwright NuGet package, even though they share similar browser download mechanisms.

Applied to files:

  • docs/modules/playwright.md
🧬 Code graph analysis (1)
src/Testcontainers.Playwright/PlaywrightBuilder.cs (2)
src/Testcontainers.Playwright/PlaywrightContainer.cs (2)
  • PublicAPI (4-36)
  • PlaywrightContainer (13-17)
src/Testcontainers.Playwright/PlaywrightConfiguration.cs (6)
  • PublicAPI (4-53)
  • PlaywrightConfiguration (10-12)
  • PlaywrightConfiguration (18-22)
  • PlaywrightConfiguration (28-32)
  • PlaywrightConfiguration (38-42)
  • PlaywrightConfiguration (49-52)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: analyze (csharp)
🔇 Additional comments (1)
docs/modules/playwright.md (1)

1-46: All external file references are verified and correctly configured.

The documentation snippet includes correctly formatted references to:

  • PlaywrightContainerTest.cs with section marker UsePlaywrightContainer (lines 42-70)
  • Testcontainers.Playwright.Tests.csproj with section marker PackageReferences (lines 9-15)
  • _call_out_test_projects.txt (exists at expected location)

Regarding the browser configuration (WithBrowser) mentioned in the review comment's enriched summary: This feature could not be verified in available documentation for Testcontainers.Playwright .NET. Without access to the actual test implementation file or the NuGet package documentation, the claim that browser selection via WithBrowser() should be documented cannot be confirmed.

Copy link
Collaborator

@HofmeisterAn HofmeisterAn left a comment

Choose a reason for hiding this comment

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

Thanks for creating the initial PR. It took me a bit to review it. Since then, quite a few things have changed. I've updated the PR and aligned it with the repo standards and switched from the custom Docker images to the official Microsoft image. Appreciate your contribution! Thanks again.

@HofmeisterAn HofmeisterAn merged commit c56984f into testcontainers:develop Nov 7, 2025
75 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request module An official Testcontainers module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants