diff --git a/playwright-dotnet/PlaywrightIPhoneTest.cs b/playwright-dotnet/PlaywrightIPhoneTest.cs index 4d6ffb9..056f139 100644 --- a/playwright-dotnet/PlaywrightIPhoneTest.cs +++ b/playwright-dotnet/PlaywrightIPhoneTest.cs @@ -29,7 +29,7 @@ public static async Task main(string[] args) await page.Locator("[aria-label='Search']").ClickAsync(); await page.FillAsync("[aria-label='Search']", "BrowserStack"); await page.Keyboard.PressAsync("Enter"); - await page.WaitForTimeoutAsync(1000); + await page.Locator("[aria-current='page']").WaitForAsync(); var title = await page.TitleAsync(); if (title == "BrowserStack - Google Search") diff --git a/playwright-dotnet/PlaywrightPixelTest.cs b/playwright-dotnet/PlaywrightPixelTest.cs index f95ec9c..20bfafa 100644 --- a/playwright-dotnet/PlaywrightPixelTest.cs +++ b/playwright-dotnet/PlaywrightPixelTest.cs @@ -29,7 +29,7 @@ public static async Task main(string[] args) await page.Locator("[aria-label='Search']").ClickAsync(); await page.FillAsync("[aria-label='Search']", "BrowserStack"); await page.Keyboard.PressAsync("Enter"); - await page.WaitForTimeoutAsync(1000); + await page.Locator("[aria-current='page']").WaitForAsync(); var title = await page.TitleAsync(); if (title == "BrowserStack - Google Search") diff --git a/playwright-dotnet/PlaywrightSessionDetailsTest.cs b/playwright-dotnet/PlaywrightSessionDetailsTest.cs new file mode 100644 index 0000000..10a2ae5 --- /dev/null +++ b/playwright-dotnet/PlaywrightSessionDetailsTest.cs @@ -0,0 +1,66 @@ +using Microsoft.Playwright; +using System.Threading.Tasks; +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + + +class PlaywrightSessionDetailsTest +{ + public static async Task main(string[] args) + { + using var playwright = await Playwright.CreateAsync(); + + Dictionary browserstackOptions = new Dictionary(); + browserstackOptions.Add("name", "Playwright first sample test"); + browserstackOptions.Add("build", "playwright-dotnet-5"); + browserstackOptions.Add("os", "osx"); + browserstackOptions.Add("os_version", "catalina"); + browserstackOptions.Add("browser", "chrome"); // allowed browsers are `chrome`, `edge`, `playwright-chromium`, `playwright-firefox` and `playwright-webkit` + browserstackOptions.Add("browserstack.username", "BROWSERSTACK_USERNAME"); + browserstackOptions.Add("browserstack.accessKey", "BROWSERSTACK_ACCESS_KEY"); + string capsJson = JsonConvert.SerializeObject(browserstackOptions); + string cdpUrl = "wss://cdp.browserstack.com/playwright?caps=" + Uri.EscapeDataString(capsJson); + + await using var browser = await playwright.Chromium.ConnectAsync(cdpUrl); + var page = await browser.NewPageAsync(); + try { + await page.GotoAsync("https://www.google.co.in/"); + await page.Locator("[aria-label='Search']").ClickAsync(); + await page.FillAsync("[aria-label='Search']", "BrowserStack"); + await page.Locator("[aria-label='Google Search'] >> nth=0").ClickAsync(); + var title = await page.TitleAsync(); + + if (title == "BrowserStack - Google Search") + { + // following line of code is responsible for marking the status of the test on BrowserStack as 'passed'. You can use this code in your after hook after each test + await MarkTestStatus("passed", "Title matched", page); + } else + { + await MarkTestStatus("failed", "Title did not match", page); + } + Object sessionObject = await page.EvaluateAsync("_ => {}", "browserstack_executor: {\"action\":\"getSessionDetails\"}"); + + // convert Object to String for parsing + string? json_resp = Convert.ToString(sessionObject); + + // parse the data + if (json_resp != null) + { + var sessionDetails = JObject.Parse(json_resp); + + // print the session Details on IDE's console + Console.WriteLine("GetSessionDetails response: \n" + sessionDetails); + } + } + catch (Exception err) { + await MarkTestStatus("failed", err.Message, page); + } + await browser.CloseAsync(); + } + + public static async Task MarkTestStatus(string status, string reason, IPage page) { + await page.EvaluateAsync("_ => {}", "browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\":\"" + status + "\", \"reason\": \"" + reason + "\"}}"); + } +} diff --git a/playwright-dotnet/Program.cs b/playwright-dotnet/Program.cs index 82b4ad9..1288510 100644 --- a/playwright-dotnet/Program.cs +++ b/playwright-dotnet/Program.cs @@ -29,6 +29,10 @@ public static async Task Main(string[] args) Console.WriteLine("Running Pixel Test"); await PlaywrightPixelTest.main(args); break; + case "sessiondetails": + Console.WriteLine("Getting Session Details Test"); + await PlaywrightSessionDetailsTest.main(args); + break; default: Console.WriteLine("Running Single Test by default"); await PlaywrightTest.main(args); diff --git a/playwright-dotnet/README.md b/playwright-dotnet/README.md index 1aa0413..d3afc0e 100644 --- a/playwright-dotnet/README.md +++ b/playwright-dotnet/README.md @@ -13,6 +13,11 @@ - To run a single test, run `dotnet run single` - To run a parallel test, run command `dotnet run parallel` +- To run sessions on emulated devices, +`dotnet run iphonetest` or `dotnet run pixeltest` +You can specify any device name from the below list: +https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/deviceDescriptorsSource.json +- Run `dotnet run sessiondetails` to check how to get session details. ### Run sample test on privately hosted websites diff --git a/playwright-java/README.md b/playwright-java/README.md index 70dc770..a8d3ced 100644 --- a/playwright-java/README.md +++ b/playwright-java/README.md @@ -16,6 +16,17 @@ - To run parallel tests, run `mvn -Dexec.mainClass="com.browserstack.PlaywrightParallelTest" -Dexec.classpathScope=test test-compile exec:java ` +- To run sessions on emulated devices, + ``` + mvn -Dexec.mainClass="com.browserstack.PlaywrightIPhoneTest" -Dexec.classpathScope=test test-compile exec:java + ``` + or + ``` + mvn -Dexec.mainClass="com.browserstack.PlaywrightPixelTest" -Dexec.classpathScope=test test-compile exec:java + ``` +You can specify contextOptions() from the below list: +https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/deviceDescriptorsSource.json +- Run `mvn -Dexec.mainClass="com.browserstack.PlaywrightSessionDetailsTest" -Dexec.classpathScope=test test-compile exec:java` to check how to get session details. ### Run sample test on privately hosted websites diff --git a/playwright-java/src/test/java/com/browserstack/PlaywrightIPhoneTest.java b/playwright-java/src/test/java/com/browserstack/PlaywrightIPhoneTest.java new file mode 100644 index 0000000..517a31a --- /dev/null +++ b/playwright-java/src/test/java/com/browserstack/PlaywrightIPhoneTest.java @@ -0,0 +1,59 @@ +package com.browserstack; + +import com.google.gson.JsonObject; +import com.microsoft.playwright.*; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + +public class PlaywrightIPhoneTest { + public static void main(String[] args) { + try (Playwright playwright = Playwright.create()) { + JsonObject capabilitiesObject = new JsonObject(); + capabilitiesObject.addProperty("browser", "playwright-webkit"); // allowed browsers are `chrome`, `edge`, `playwright-chromium`, `playwright-firefox` and `playwright-webkit` + capabilitiesObject.addProperty("browser_version", "latest"); + capabilitiesObject.addProperty("name", "Test on Playwright emulated Devices"); + capabilitiesObject.addProperty("build", "playwright-java-4"); + capabilitiesObject.addProperty("browserstack.username", "BROWSERSTACK_USERNAME"); + capabilitiesObject.addProperty("browserstack.accessKey", "BROWSERSTACK_ACCESS_KEY"); + + BrowserType chromium = playwright.chromium(); + String caps = URLEncoder.encode(capabilitiesObject.toString(), "utf-8"); + String ws_endpoint = "wss://cdp.browserstack.com/playwright?caps=" + caps; + + Browser browser = chromium.connect(ws_endpoint); + BrowserContext context = browser.newContext(new Browser.NewContextOptions() + .setUserAgent("Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Mobile/15E148 Safari/604.1") + .setViewportSize(375, 812) + .setDeviceScaleFactor(3) + .setIsMobile(true) + .setHasTouch(true)); + + Page page = context.newPage(); + try { + page.navigate("https://www.google.co.in/"); + Locator locator = page.locator("[aria-label='Search']"); + locator.click(); + page.fill("[aria-label='Search']", "BrowserStack"); + page.keyboard().press("Enter"); + page.locator("[aria-current='page']").waitFor(); + String title = page.title(); + + if (title.equals("BrowserStack - Google Search")) { + // following line of code is responsible for marking the status of the test on BrowserStack as 'passed'. You can use this code in your after hook after each test + markTestStatus("passed", "Title matched", page); + } else { + markTestStatus("failed", "Title did not match", page); + } + } catch (Exception err) { + markTestStatus("failed", err.getMessage(), page); + } + browser.close(); + } catch (UnsupportedEncodingException e) { + System.out.println(e); + } + } + public static void markTestStatus(String status, String reason, Page page) { + Object result; + result = page.evaluate("_ => {}", "browserstack_executor: { \"action\": \"setSessionStatus\", \"arguments\": { \"status\": \"" + status + "\", \"reason\": \"" + reason + "\"}}"); + } +} diff --git a/playwright-java/src/test/java/com/browserstack/PlaywrightPixelTest.java b/playwright-java/src/test/java/com/browserstack/PlaywrightPixelTest.java new file mode 100644 index 0000000..8ab5aed --- /dev/null +++ b/playwright-java/src/test/java/com/browserstack/PlaywrightPixelTest.java @@ -0,0 +1,60 @@ +package com.browserstack; + +import com.google.gson.JsonObject; +import com.microsoft.playwright.*; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + +public class PlaywrightPixelTest { + public static void main(String[] args) { + try (Playwright playwright = Playwright.create()) { + JsonObject capabilitiesObject = new JsonObject(); + capabilitiesObject.addProperty("browser", "playwright-webkit"); // allowed browsers are `chrome`, `edge`, `playwright-chromium`, `playwright-firefox` and `playwright-webkit` + capabilitiesObject.addProperty("browser_version", "latest"); + capabilitiesObject.addProperty("name", "Test on Playwright emulated Devices"); + capabilitiesObject.addProperty("build", "playwright-java-4"); + capabilitiesObject.addProperty("browserstack.username", "BROWSERSTACK_USERNAME"); + capabilitiesObject.addProperty("browserstack.accessKey", "BROWSERSTACK_ACCESS_KEY"); + + BrowserType chromium = playwright.chromium(); + String caps = URLEncoder.encode(capabilitiesObject.toString(), "utf-8"); + String ws_endpoint = "wss://cdp.browserstack.com/playwright?caps=" + caps; + + Browser browser = chromium.connect(ws_endpoint); + BrowserContext context = browser.newContext(new Browser.NewContextOptions() + .setUserAgent("Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4943.0 Mobile Safari/537.36") + .setViewportSize(393, 727) + .setScreenSize(393, 851) + .setDeviceScaleFactor(3) + .setIsMobile(true) + .setHasTouch(true)); + + Page page = context.newPage(); + try { + page.navigate("https://www.google.co.in/"); + Locator locator = page.locator("[aria-label='Search']"); + locator.click(); + page.fill("[aria-label='Search']", "BrowserStack"); + page.keyboard().press("Enter"); + page.locator("[aria-current='page']").waitFor(); + String title = page.title(); + + if (title.equals("BrowserStack - Google Search")) { + // following line of code is responsible for marking the status of the test on BrowserStack as 'passed'. You can use this code in your after hook after each test + markTestStatus("passed", "Title matched", page); + } else { + markTestStatus("passed", "Title did not match", page); + } + } catch (Exception err) { + markTestStatus("failed", err.getMessage(), page); + } + browser.close(); + } catch (UnsupportedEncodingException e) { + System.out.println(e); + } + } + public static void markTestStatus(String status, String reason, Page page) { + Object result; + result = page.evaluate("_ => {}", "browserstack_executor: { \"action\": \"setSessionStatus\", \"arguments\": { \"status\": \"" + status + "\", \"reason\": \"" + reason + "\"}}"); + } +} diff --git a/playwright-java/src/test/java/com/browserstack/PlaywrightSessionDetailsTest.java b/playwright-java/src/test/java/com/browserstack/PlaywrightSessionDetailsTest.java new file mode 100644 index 0000000..f56bf9b --- /dev/null +++ b/playwright-java/src/test/java/com/browserstack/PlaywrightSessionDetailsTest.java @@ -0,0 +1,62 @@ +package com.browserstack; + +import com.google.gson.JsonObject; +import com.microsoft.playwright.*; +import com.google.gson.JsonParser; + +import java.net.URLEncoder; + +public class PlaywrightSessionDetailsTest { + public static void main(String[] args) { + try (Playwright playwright = Playwright.create()) { + JsonObject capabilitiesObject = new JsonObject(); + capabilitiesObject.addProperty("browser", "chrome"); // allowed browsers are `chrome`, `edge`, `playwright-chromium`, `playwright-firefox` and `playwright-webkit` + capabilitiesObject.addProperty("browser_version", "latest"); + capabilitiesObject.addProperty("os", "osx"); + capabilitiesObject.addProperty("os_version", "catalina"); + capabilitiesObject.addProperty("name", "Playwright first single test"); + capabilitiesObject.addProperty("build", "playwright-java-5"); + capabilitiesObject.addProperty("browserstack.username", "BROWSERSTACK_USERNAME"); + capabilitiesObject.addProperty("browserstack.accessKey", "BROWSERSTACK_ACCESS_KEY"); + + BrowserType chromium = playwright.chromium(); + String caps = URLEncoder.encode(capabilitiesObject.toString(), "utf-8"); + String ws_endpoint = "wss://cdp.browserstack.com/playwright?caps=" + caps; + Browser browser = chromium.connect(ws_endpoint); + Page page = browser.newPage(); + try { + page.navigate("https://www.google.co.in/"); + Locator locator = page.locator("[aria-label='Search']"); + locator.click(); + page.fill("[aria-label='Search']", "BrowserStack"); + page.locator("[aria-label='Google Search'] >> nth=0").click(); + String title = page.title(); + + if (title.equals("BrowserStack - Google Search")) { + // following line of code is responsible for marking the status of the test on BrowserStack as 'passed'. You can use this code in your after hook after each test + markTestStatus("passed", "Title matched", page); + } else { + markTestStatus("failed", "Title did not match", page); + } + + // store the JSON response in the Object class + Object response = page.evaluate("_ => {}", "browserstack_executor: {\"action\": \"getSessionDetails\"}"); + + // parse the JSON response + JsonObject sessionDetails = JsonParser.parseString((String) response).getAsJsonObject(); + + // print session Details in your IDE's console + System.out.println("GetSessionDetails response: \n" + sessionDetails); + } catch (Exception err) { + markTestStatus("failed", err.getMessage(), page); + } + browser.close(); + } catch (Exception err) { + System.out.println(err); + } + } + public static void markTestStatus(String status, String reason, Page page) { + Object result; + result = page.evaluate("_ => {}", "browserstack_executor: { \"action\": \"setSessionStatus\", \"arguments\": { \"status\": \"" + status + "\", \"reason\": \"" + reason + "\"}}"); + } +} diff --git a/playwright-python/README.md b/playwright-python/README.md index 6337517..ffe12ea 100644 --- a/playwright-python/README.md +++ b/playwright-python/README.md @@ -19,6 +19,11 @@ - To run a single test, run `python single-playwright-test.py` - To run parallel tests, run `python parallel-playwright-test.py` +- To run sessions on emulated devices, +`python playwright-test-on-iphone.py` or `python playwright-test-on-pixel.py` +You can specify any device name from the below list: +https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/deviceDescriptorsSource.json +- Run `python session-details-playwright-test.py` to check how to get session details. ### Run sample test on privately hosted websites **Using Language Bindings** diff --git a/playwright-python/playwright-test-on-iphone.py b/playwright-python/playwright-test-on-iphone.py index 44c6d82..2b9f5a6 100644 --- a/playwright-python/playwright-test-on-iphone.py +++ b/playwright-python/playwright-test-on-iphone.py @@ -25,7 +25,7 @@ def run_session(playwright): page.goto("https://www.google.co.in/") page.fill("[aria-label='Search']", 'Browserstack') page.keyboard.press('Enter') - page.wait_for_timeout(1000) + page.locator("[aria-current='page']").wait_for(); title = page.title() if title == "Browserstack - Google Search": diff --git a/playwright-python/playwright-test-on-pixel.py b/playwright-python/playwright-test-on-pixel.py index ce115df..b8579d6 100644 --- a/playwright-python/playwright-test-on-pixel.py +++ b/playwright-python/playwright-test-on-pixel.py @@ -25,7 +25,7 @@ def run_session(playwright): page.goto("https://www.google.co.in/") page.fill("[aria-label='Search']", 'Browserstack') page.keyboard.press('Enter') - page.wait_for_timeout(1000) + page.locator("[aria-current='page']").wait_for(); title = page.title() if title == "Browserstack - Google Search": diff --git a/playwright-python/session-details-playwright-test.py b/playwright-python/session-details-playwright-test.py new file mode 100644 index 0000000..dd11cca --- /dev/null +++ b/playwright-python/session-details-playwright-test.py @@ -0,0 +1,51 @@ +import json +import urllib +from playwright.sync_api import sync_playwright + +desired_cap = { + 'browser': 'chrome', # allowed browsers are `chrome`, `edge`, `playwright-chromium`, `playwright-firefox` and `playwright-webkit` + 'browser_version': 'latest', # this capability is valid only for branded `chrome` and `edge` browsers and you can specify any browser version like `latest`, `latest-beta`, `latest-1` and so on. + 'os': 'osx', + 'os_version': 'catalina', + 'name': 'Branded Google Chrome on Catalina', + 'build': 'playwright-python-5', + 'browserstack.username': 'BROWSERSTACK_USERNAME', + 'browserstack.accessKey': 'BROWSERSTACK_ACCESS_KEY' +} + +def run_session(playwright): + cdpUrl = 'wss://cdp.browserstack.com/playwright?caps=' + urllib.parse.quote(json.dumps(desired_cap)) + browser = playwright.chromium.connect(cdpUrl) + page = browser.new_page() + try: + page.goto("https://www.google.co.in/") + page.fill("[aria-label='Search']", 'Browserstack') + locator = page.locator("[aria-label='Google Search'] >> nth=0") + locator.click() + title = page.title() + + if title == "Browserstack - Google Search": + # following line of code is responsible for marking the status of the test on BrowserStack as 'passed'. You can use this code in your after hook after each test + mark_test_status("passed", "Title matched", page) + else: + mark_test_status("failed", "Title did not match", page) + + # get details of the session + response = page.evaluate("_=> {}", 'browserstack_executor: {"action": "getSessionDetails"}') + + session_details= json.loads(response) + + # print the session Details in the IDE's console + print("GetSessionDetails response: \n", session_details) + + except Exception as err: + mark_test_status("failed", str(err), page) + + browser.close() + +def mark_test_status(status, reason, page): + page.evaluate("_ => {}", "browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\":\""+ status + "\", \"reason\": \"" + reason + "\"}}"); + +with sync_playwright() as playwright: + run_session(playwright) +