If you must run Playwright on a specific browser, you will find a service like BrowserStack a great help. Let’s look how we can connect Playwright to BrowserStack and Selenium Grid.
This post is part of my journey to learn Python. You can find the other parts of this series here. You find the code for this post in my PythonFriday repository on GitHub.
Prerequisites for BrowserStack
For BrowserStack we need an account that can run code on the Automate feature. If you do not already have an account, you can create one for free and test BrowserStack.
Connect to BrowserStack
As with .Net you can get the example for Python directly from BrowserStack. I only shortened a few lines and use the .env file for the credentials.
Since BrowserStack offers such a large variety of browsers and operating systems, we need to specify what combination we want to use. We can define the desired capabilities in the desired_cap dictionary. That is also the place where we need to set the credentials for BrowserStack – otherwise we get a strange exception.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
import json import urllib import subprocess from playwright.sync_api import sync_playwright from dotenv import load_dotenv import os load_dotenv() desired_cap = { # allowed browsers are `chrome`, `edge`, `playwright-chromium`, # `playwright-firefox` and `playwright-webkit` 'browser': 'chrome', # 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. 'browser_version': 'latest', 'os': 'osx', 'os_version': 'catalina', 'name': 'Branded Google Chrome on Catalina', 'build': 'playwright-python-1', 'browserstack.username': f'{os.getenv("user")}', 'browserstack.accessKey': f'{os.getenv("accessKey")}' } def run_session(playwright): version = str(subprocess.getoutput('playwright --version')) clientPlaywrightVersion = version.strip().split(" ")[1] desired_cap['client.playwrightVersion'] = clientPlaywrightVersion cap_quoted = urllib.parse.quote(json.dumps(desired_cap)) cdpUrl = 'wss://cdp.browserstack.com/playwright?caps=' + cap_quoted 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) 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) |
If we run the application, we get a video and a detailed list of the activities on BrowserStack:
Marking the state of the test in BrowserStack did not work with Playwright 1.27 and 1.28. I hope this will work with newer versions.
Prerequisites for Selenium Grid
We need to create a dynamic Selenium Grid on Docker. You find both necessary files to configure the grid in my C# post Run Playwright on Selenium Grid.
When you saved the files, you can run the grid with this command:
1 |
docker-compose -f docker-compose-v3-dynamic-grid.yml up |
Run your code in Selenium Grid
We use this little application to test Selenium Grid:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
from playwright.sync_api import Playwright, sync_playwright, expect def run(playwright: Playwright) -> None: browser = playwright.chromium.launch(headless=False) context = browser.new_context() page = context.new_page() page.goto("https://www.whatismybrowser.com/") version = page.locator("#primary-browser-detection").inner_text() print(version) # --------------------- context.close() browser.close() with sync_playwright() as playwright: run(playwright) |
When we run this application, it should give us an output like this:
1 |
python .\playwright_seleniumgrid.py |
YOUR WEB BROWSER IS:
Chrome 108 on Windows 11
We can switch to Selenium Grid by setting the environment variable SELENIUM_REMOTE_URL
to our grid:
1 |
$env:SELENIUM_REMOTE_URL='http://localhost:4444/wd/hub' |
If we now run the application again, it uses Selenium Grid and produces an output like this one:
1 |
python .\playwright_seleniumgrid.py |
YOUR WEB BROWSER IS:
Chrome 106 on Linux
You can set the environment variable inside your code, but it is not necessary.
Next
This concludes the Python specific posts on Playwright. As you could see over the last few weeks, there is much similarity between C# and Python when it comes to Playwright. Usually, the code is a little bit simpler on Python, but there are no meaningful differences.
Next Tuesday I conclude my posts on Playwright with a recapitulation of the covered topics and answer the question if you should switch to Playwright.