From 929a390edba0b3f57279000d308c73e3dee32154 Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Wed, 17 Jun 2026 15:44:59 +0530 Subject: [PATCH 1/5] docs(playwright-android): fix sample scripts and use chromium.connect() - Use chromium.connect() across Node.js, Java, C#, and Python (drop connectOverCDP) - Node.js: switch to chromium-based connect flow with context/page reuse - Java: replace Map.of() (11 entries fails to compile) with LinkedHashMap; add playwrightClientVersion - C#: drop System.Web/HttpUtility, use Uri.EscapeDataString - Update Supported Versions note to reflect the unified connect() API Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/playwright-android-guide.md | 90 ++++++++++++++++---------------- 1 file changed, 44 insertions(+), 46 deletions(-) diff --git a/docs/playwright-android-guide.md b/docs/playwright-android-guide.md index 09ea8854e..4a66e5951 100644 --- a/docs/playwright-android-guide.md +++ b/docs/playwright-android-guide.md @@ -54,7 +54,7 @@ Playwright Android automation is supported on across **Node.js, Ja :::tip Supported Versions - Playwright versions **v1.20.0** to **v1.59.0** are supported for Android real device testing (excluding `v1.54.0`). -- **Node.js** uses the `_android.connect()` API. **Java, C#, and Python** use `chromium.connectOverCDP()`. All use stock Playwright packages, no custom forks required. +- **Node.js, Java, C#, and Python** all use the `chromium.connect()` API. All use stock Playwright packages, no custom forks required. - Playwright v1.53.0 is currently supported for Playwright C# (for Android & iOS). ::: @@ -142,39 +142,35 @@ dotnet add package Microsoft.Playwright ```javascript title="playwright-android-test.js" -const { _android } = require("playwright"); +const { chromium } = require("playwright"); (async () => { const capabilities = { "LT:Options": { - "platformName": "android", - "deviceName": "Pixel 5", - "platformVersion": "11", - "isRealMobile": true, - "build": "Playwright Android Build", - "name": "Playwright Android Test", - "user": process.env.LT_USERNAME, - "accessKey": process.env.LT_ACCESS_KEY, - "network": true, - "video": true, - "console": true, + platformName: "android", + deviceName: "Pixel 5", + platformVersion: "11", + isRealMobile: true, + build: "Playwright Android Build", + name: "Playwright Android Test", + user: process.env.LT_USERNAME, + accessKey: process.env.LT_ACCESS_KEY, + network: true, + video: true, + console: true, + playwrightClientVersion: "1.53.0", }, }; - const device = await _android.connect( - `wss://cdp.lambdatest.com/playwright?capabilities=${encodeURIComponent( - JSON.stringify(capabilities) - )}` - ); + const cdpUrl = `wss://cdp.lambdatest.com/playwright?capabilities=${encodeURIComponent( + JSON.stringify(capabilities) + )}`; - console.log(`Model: ${device.model()}, Serial: ${device.serial()}`); - await device.shell("am force-stop com.android.chrome"); + const browser = await chromium.connect(cdpUrl); + const context = browser.contexts()[0] || (await browser.newContext()); + const page = context.pages()[0] || (await context.newPage()); - const context = await device.launchBrowser(); - context.setDefaultTimeout(120000); - const page = await context.newPage(); - - await page.goto("https://duckduckgo.com"); + await page.goto("https://duckduckgo.com", { timeout: 30000 }); await page.locator('[name="q"]').fill("LambdaTest"); await page.locator('[name="q"]').press("Enter"); await page.waitForTimeout(3000); @@ -204,7 +200,7 @@ const { _android } = require("playwright"); await page.close(); await context.close(); - await device.close(); + await browser.close(); })(); ``` @@ -253,7 +249,7 @@ def main(): ) with sync_playwright() as p: - browser = p.chromium.connect_over_cdp(cdp_url) + browser = p.chromium.connect(cdp_url) context = browser.contexts[0] if browser.contexts else browser.new_context() page = context.pages[0] if context.pages else context.new_page() @@ -302,31 +298,34 @@ import com.microsoft.playwright.*; import com.google.gson.Gson; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.LinkedHashMap; import java.util.Map; public class PlaywrightAndroidTest { public static void main(String[] args) { - Map ltOptions = Map.of( - "platformName", "android", - "deviceName", "Pixel 5", - "platformVersion", "11", - "isRealMobile", true, - "build", "Playwright Android Build", - "name", "Playwright Android Test", - "user", System.getenv("LT_USERNAME"), - "accessKey", System.getenv("LT_ACCESS_KEY"), - "network", true, - "video", true, - "console", true - ); - - Map capabilities = Map.of("LT:Options", ltOptions); + Map ltOptions = new LinkedHashMap<>(); + ltOptions.put("platformName", "android"); + ltOptions.put("deviceName", "Pixel 5"); + ltOptions.put("platformVersion", "11"); + ltOptions.put("isRealMobile", true); + ltOptions.put("build", "Playwright Android Build"); + ltOptions.put("name", "Playwright Android Test"); + ltOptions.put("user", System.getenv("LT_USERNAME")); + ltOptions.put("accessKey", System.getenv("LT_ACCESS_KEY")); + ltOptions.put("network", true); + ltOptions.put("video", true); + ltOptions.put("console", true); + ltOptions.put("playwrightClientVersion", "1.53.0"); + + Map capabilities = new LinkedHashMap<>(); + capabilities.put("LT:Options", ltOptions); + String capsJson = new Gson().toJson(capabilities); String cdpUrl = "wss://cdp.lambdatest.com/playwright?capabilities=" + URLEncoder.encode(capsJson, StandardCharsets.UTF_8); try (Playwright playwright = Playwright.create()) { - Browser browser = playwright.chromium().connectOverCDP(cdpUrl); + Browser browser = playwright.chromium().connect(cdpUrl); BrowserContext context = browser.contexts().size() > 0 ? browser.contexts().get(0) : browser.newContext(); Page page = context.pages().size() > 0 @@ -372,7 +371,6 @@ mvn compile exec:java -Dexec.mainClass="com.lambdatest.PlaywrightAndroidTest" ```csharp title="PlaywrightAndroidTest.cs" using Microsoft.Playwright; using System.Text.Json; -using System.Web; var capabilities = new Dictionary { @@ -394,10 +392,10 @@ var capabilities = new Dictionary }; var capsJson = JsonSerializer.Serialize(capabilities); -var cdpUrl = $"wss://cdp.lambdatest.com/playwright?capabilities={HttpUtility.UrlEncode(capsJson)}"; +var cdpUrl = $"wss://cdp.lambdatest.com/playwright?capabilities={Uri.EscapeDataString(capsJson)}"; using var playwright = await Playwright.CreateAsync(); -var browser = await playwright.Chromium.ConnectOverCDPAsync(cdpUrl); +var browser = await playwright.Chromium.ConnectAsync(cdpUrl); var context = browser.Contexts.Count > 0 ? browser.Contexts[0] : await browser.NewContextAsync(); var page = context.Pages.Count > 0 From 88c29a7cb5bfc6384f24892334325929202b7961 Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Wed, 17 Jun 2026 18:25:43 +0530 Subject: [PATCH 2/5] docs(playwright-android): drop context.close() and add _android.connect() for Node - Remove context.close()/CloseAsync() from all four samples (browser.close() handles teardown) - Node.js: add an _android.connect() example alongside chromium.connect() (Node supports both) - Update Supported Versions note: Node supports both APIs; Java/C#/Python use chromium.connect() Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/playwright-android-guide.md | 78 ++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 5 deletions(-) diff --git a/docs/playwright-android-guide.md b/docs/playwright-android-guide.md index 4a66e5951..9bc4ff9ea 100644 --- a/docs/playwright-android-guide.md +++ b/docs/playwright-android-guide.md @@ -54,7 +54,7 @@ Playwright Android automation is supported on across **Node.js, Ja :::tip Supported Versions - Playwright versions **v1.20.0** to **v1.59.0** are supported for Android real device testing (excluding `v1.54.0`). -- **Node.js, Java, C#, and Python** all use the `chromium.connect()` API. All use stock Playwright packages, no custom forks required. +- **Java, C#, and Python** use the `chromium.connect()` API. **Node.js** supports both `chromium.connect()` and the Android-native `_android.connect()` API. All use stock Playwright packages, no custom forks required. - Playwright v1.53.0 is currently supported for Playwright C# (for Android & iOS). ::: @@ -141,6 +141,10 @@ dotnet add package Microsoft.Playwright +Node.js supports both the Chromium API (`chromium.connect()`) and the Android-native API (`_android.connect()`). + +**Using `chromium.connect()`** + ```javascript title="playwright-android-test.js" const { chromium } = require("playwright"); @@ -199,11 +203,78 @@ const { chromium } = require("playwright"); } await page.close(); - await context.close(); await browser.close(); })(); ``` +**Using `_android.connect()`** + +```javascript title="playwright-android-test.js" +const { _android } = require("playwright"); + +(async () => { + const capabilities = { + "LT:Options": { + platformName: "android", + deviceName: "Pixel 5", + platformVersion: "11", + isRealMobile: true, + build: "Playwright Android Build", + name: "Playwright Android Test", + user: process.env.LT_USERNAME, + accessKey: process.env.LT_ACCESS_KEY, + network: true, + video: true, + console: true, + playwrightClientVersion: "1.53.0", + }, + }; + + const cdpUrl = `wss://cdp.lambdatest.com/playwright?capabilities=${encodeURIComponent( + JSON.stringify(capabilities) + )}`; + + const device = await _android.connect(cdpUrl); + console.log(`Model: ${device.model()}, Serial: ${device.serial()}`); + await device.shell("am force-stop com.android.chrome"); + + const context = await device.launchBrowser(); + context.setDefaultTimeout(120000); + const page = await context.newPage(); + + await page.goto("https://duckduckgo.com"); + await page.locator('[name="q"]').fill("LambdaTest"); + await page.locator('[name="q"]').press("Enter"); + await page.waitForTimeout(3000); + + const title = await page.title(); + console.log("Page title:", title); + + try { + if (title.includes("LambdaTest")) { + await page.evaluate( + (_) => {}, + `lambdatest_action: ${JSON.stringify({ + action: "setTestStatus", + arguments: { status: "passed", remark: "Title verified" }, + })}` + ); + } + } catch (e) { + await page.evaluate( + (_) => {}, + `lambdatest_action: ${JSON.stringify({ + action: "setTestStatus", + arguments: { status: "failed", remark: e.message }, + })}` + ); + } + + await page.close(); + await device.close(); +})(); +``` + :::tip The timeout value specified in the Playwright configuration may default to 30 seconds on real devices. To set a custom timeout, add: @@ -274,7 +345,6 @@ def main(): ) page.close() - context.close() browser.close() if __name__ == "__main__": @@ -351,7 +421,6 @@ public class PlaywrightAndroidTest { } page.close(); - context.close(); browser.close(); } } @@ -424,7 +493,6 @@ catch (Exception e) } await page.CloseAsync(); -await context.CloseAsync(); await browser.CloseAsync(); ``` From 92b360e7ff577beac6fb886ae7885eaffafe8303 Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Wed, 17 Jun 2026 19:57:42 +0530 Subject: [PATCH 3/5] docs(playwright-ios): add Beta notice above Supported Versions Add an "info Currently in BETA" admonition noting that Playwright on real iOS devices is in Beta and that users must contact their account team to enable the feature flag. Matches the beta-callout design used elsewhere. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/playwright-ios-guide.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/playwright-ios-guide.md b/docs/playwright-ios-guide.md index a0f20d85d..f524e2918 100644 --- a/docs/playwright-ios-guide.md +++ b/docs/playwright-ios-guide.md @@ -54,6 +54,12 @@ Playwright test automation on real iOS devices is now supported on This guide will cover the basics of getting started with Playwright testing on iOS devices on the platform. +:::info Currently in BETA + +Playwright testing on real iOS devices is currently in **Beta**. To enable this feature for your organization, please contact your window.openLTChatWidget()}>account team to have the feature flag turned on. + +::: + :::tip Supported Versions - Playwright versions **v1.53.0** and above (until **v1.57.0**) are supported for iOS real device testing. - All languages use the **stock Playwright packages** — no custom forks or client-side changes required. From c089628e831b51218e41a15d19a50944f534e45a Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Wed, 17 Jun 2026 20:29:06 +0530 Subject: [PATCH 4/5] fix(kane-cli): quote front-matter description to fix YAML parse error The unquoted `description` contained an internal ": " ("plain English: from your terminal"), which YAML parses as a nested mapping key. This broke the Docusaurus build and has been failing every Stage deployment since #3122, blocking all docs from deploying to stage. Wrapping the value in quotes fixes it. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/kane-cli-introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/kane-cli-introduction.md b/docs/kane-cli-introduction.md index 95947c432..1032027b9 100644 --- a/docs/kane-cli-introduction.md +++ b/docs/kane-cli-introduction.md @@ -2,7 +2,7 @@ id: kane-cli-introduction title: Kane CLI Documentation - Getting Started sidebar_label: Introduction -description: Kane CLI is an AI-powered command-line tool that runs browser automation tests in plain English: from your terminal, IDE, or CI pipeline. +description: "Kane CLI is an AI-powered command-line tool that runs browser automation tests in plain English: from your terminal, IDE, or CI pipeline." keywords: - kane cli - kaneai From 2b2feaec089e03dcb0f3538a0fc73540c07829d5 Mon Sep 17 00:00:00 2001 From: abhishekkumar Date: Wed, 17 Jun 2026 22:25:49 +0530 Subject: [PATCH 5/5] Update environment_id to configuration_id --- docs/kaneai-github-app.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/kaneai-github-app.md b/docs/kaneai-github-app.md index 98842cdc6..30e57b71c 100644 --- a/docs/kaneai-github-app.md +++ b/docs/kaneai-github-app.md @@ -181,7 +181,7 @@ Create a `.lambdatest/config.yaml` file in the root directory of your repository project_id: "your_project_id" folder_id: "your_folder_id" assignee: your_user_id -environment_id: environment_id +configuration_id: configuration_id test_url: "https://your-deployed-app-url.com/" tunnel_name: "your_tunnel_name" # Optional: set if using the same tunnel across PRs ``` @@ -193,7 +193,7 @@ tunnel_name: "your_tunnel_name" # Optional: set if using the same tunnel across | `project_id` | The unique identifier for your Test Manager project | | `folder_id` | The folder where generated test cases will be organized | | `assignee` | The user ID who will be assigned to test runs for executions | -| `environment_id` | The target testing environment (browser, OS, device configurations) | +| `configuration_id` | The target testing environment (browser, OS, device configurations) | | `test_url` | The base URL of your application under test (your staging or testing environment URL) | | `tunnel_name` | *(Optional)* The name of the LambdaTest tunnel to use for testing. Set this when the same tunnel is reused across all PRs. Can be overridden per PR using the `--tunnel` flag in the trigger comment. |