SlideShare a Scribd company logo
ITB 2023 cbPlaywright End-to-end Tests with Playwright and TestBox - Eric Petersen.pdf
https://slides.com/elpete/itb2023-cbplaywright
What this talk is
An overview of cbPlaywright
An overview of Playwright Java
How to use the companion
CommandBox library
A few end-to-end testing selector
strategies
Live coding cbPlaywright tests
What this talk isn't
About unit, integration, or any other
kind of testing besides end-to-end (or
browser) tests
Comparison to other end-to-end
testing tools
Deep dive into end-to-end testing best
practices
ITB 2023 cbPlaywright End-to-end Tests with Playwright and TestBox - Eric Petersen.pdf
What is
cbPlaywright?
Includes the necessary jars and drivers to run
Playwright Java
Provides integration with TestBox and ColdBox
tests
Helper methods for making interacting with
Playwright Java easier
What is cbPlaywright?
So...what is
Playwright?
CFML
If Playwright Java
exists...why would I
use cbPlaywright?
Includes the necessary jars
to run Playwright Java
Companion CommandBox module for downloading the
correct platform drivers
Helper functions to turn this....
var screenshotOptions = createObject( "java", "com.microsoft.playwright.Page$ScreenshotOptions" ).init();
var screenshotPath = createObject( "java", "java.nio.file.Paths" ).get(
javacast( "String", expandPath( "/tests/results/screenshotOne.png" ) ), javacast( "String[]", [] )
);
screenshotOptions.setPath( screenshotPath );
page.screenshot( screenshotOptions );
1
2
3
4
5
6
...into this
screenshotPage( page, "/tests/results/screenshotOne.png" );
1
Installation
box install cbPlaywright
Unfortunately, there is more this time....
There's this thing called a driver....
Running the driver from the Playwright Java jars was
finicky
The driver-bundle jar is very large (about 200 MB
unzipped)
The driver-bundle included versions for all the
platforms
You ended up downloading a full driver-bundle for
every cbPlaywright installation.
Interacting with the driver CLI was a pain
CommandBox cbPlaywright
CommandBox cbPlaywright
Installs as a dependency of cbPlaywright
Manages installing the correct driver for your
platform
Automatically downloads a driver on install
Provides a passthrough to the Playwright CLI
# Install the Playwright driver
cbplaywright driver install
# Install Chromium as a test browser
playwright install chromium
1
2
3
4
5
Configuration
// tests/Application.cfc
component {
this.javaSettings = {
loadPaths: directoryList(
rootPath & "modules/cbPlaywright/lib",
true,
"array",
"*jar"
),
loadColdFusionClassPath: true,
reloadOnChange: false
};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Add the Jar Paths
// tests/Application.cfc
component {
this.mappings[ "/cbPlaywright" ] = rootPath & "/modules/cbPlaywright";
}
1
2
3
4
5
6
Create a Mapping
// .env
CBPLAYWRIGHT_DRIVER_DIR=/path/to/driver/directory
1
2
Set the Driver Path
(OPTIONAL)
Usage
Creating a Test
component extends="cbPlaywright.models.PlaywrightTestCase" {
function run() {
// ...
}
}
1
2
3
4
5
6
7
Extend the Playwright Test Case
component extends="cbPlaywright.models.ColdBoxPlaywrightTestCase" {
function run() {
// ...
}
}
1
2
3
4
5
6
7
component extends="cbPlaywright.models.PlaywrightTestCase" {
function run() {
describe( "Playwright Tests", () => {
it( "can visit the Google homepage", () => {
var browser = launchBrowser( variables.playwright.chromium() );
var page = browser.newPage();
navigate( page, "https://google.com" );
waitForLoadState( page );
expect( page.title() ).toBe( "Google" );
} );
} );
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Visit a Page
component extends="cbPlaywright.models.PlaywrightTestCase" {
function run() {
describe( "Playwright Tests", () => {
it( "can visit the Google homepage", () => {
var browser = launchBrowser( variables.playwright.chromium() );
var page = browser.newPage();
navigate( page, "https://google.com" );
waitForLoadState( page );
expect( page.title() ).toBe( "Google" );
} );
} );
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var browser = launchBrowser( variables.playwright.chromium() );
component extends="cbPlaywright.models.PlaywrightTestCase" {
1
2
function run() {
3
describe( "Playwright Tests", () => {
4
it( "can visit the Google homepage", () => {
5
6
var page = browser.newPage();
7
navigate( page, "https://google.com" );
8
waitForLoadState( page );
9
expect( page.title() ).toBe( "Google" );
10
} );
11
} );
12
}
13
14
}
15
Visit a Page
component extends="cbPlaywright.models.PlaywrightTestCase" {
function run() {
describe( "Playwright Tests", () => {
it( "can visit the Google homepage", () => {
var browser = launchBrowser( variables.playwright.chromium() );
var page = browser.newPage();
navigate( page, "https://google.com" );
waitForLoadState( page );
expect( page.title() ).toBe( "Google" );
} );
} );
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var browser = launchBrowser( variables.playwright.chromium() );
component extends="cbPlaywright.models.PlaywrightTestCase" {
1
2
function run() {
3
describe( "Playwright Tests", () => {
4
it( "can visit the Google homepage", () => {
5
6
var page = browser.newPage();
7
navigate( page, "https://google.com" );
8
waitForLoadState( page );
9
expect( page.title() ).toBe( "Google" );
10
} );
11
} );
12
}
13
14
}
15
var page = browser.newPage();
component extends="cbPlaywright.models.PlaywrightTestCase" {
1
2
function run() {
3
describe( "Playwright Tests", () => {
4
it( "can visit the Google homepage", () => {
5
var browser = launchBrowser( variables.playwright.chromium() );
6
7
navigate( page, "https://google.com" );
8
waitForLoadState( page );
9
expect( page.title() ).toBe( "Google" );
10
} );
11
} );
12
}
13
14
}
15
Visit a Page
component extends="cbPlaywright.models.PlaywrightTestCase" {
function run() {
describe( "Playwright Tests", () => {
it( "can visit the Google homepage", () => {
var browser = launchBrowser( variables.playwright.chromium() );
var page = browser.newPage();
navigate( page, "https://google.com" );
waitForLoadState( page );
expect( page.title() ).toBe( "Google" );
} );
} );
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var browser = launchBrowser( variables.playwright.chromium() );
component extends="cbPlaywright.models.PlaywrightTestCase" {
1
2
function run() {
3
describe( "Playwright Tests", () => {
4
it( "can visit the Google homepage", () => {
5
6
var page = browser.newPage();
7
navigate( page, "https://google.com" );
8
waitForLoadState( page );
9
expect( page.title() ).toBe( "Google" );
10
} );
11
} );
12
}
13
14
}
15
var page = browser.newPage();
component extends="cbPlaywright.models.PlaywrightTestCase" {
1
2
function run() {
3
describe( "Playwright Tests", () => {
4
it( "can visit the Google homepage", () => {
5
var browser = launchBrowser( variables.playwright.chromium() );
6
7
navigate( page, "https://google.com" );
8
waitForLoadState( page );
9
expect( page.title() ).toBe( "Google" );
10
} );
11
} );
12
}
13
14
}
15
navigate( page, "https://google.com" );
waitForLoadState( page );
component extends="cbPlaywright.models.PlaywrightTestCase" {
1
2
function run() {
3
describe( "Playwright Tests", () => {
4
it( "can visit the Google homepage", () => {
5
var browser = launchBrowser( variables.playwright.chromium() );
6
var page = browser.newPage();
7
8
9
expect( page.title() ).toBe( "Google" );
10
} );
11
} );
12
}
13
14
}
15
Visit a Page
component extends="cbPlaywright.models.PlaywrightTestCase" {
function run() {
describe( "Playwright Tests", () => {
it( "can visit the Google homepage", () => {
var browser = launchBrowser( variables.playwright.chromium() );
var page = browser.newPage();
navigate( page, "https://google.com" );
waitForLoadState( page );
expect( page.title() ).toBe( "Google" );
} );
} );
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var browser = launchBrowser( variables.playwright.chromium() );
component extends="cbPlaywright.models.PlaywrightTestCase" {
1
2
function run() {
3
describe( "Playwright Tests", () => {
4
it( "can visit the Google homepage", () => {
5
6
var page = browser.newPage();
7
navigate( page, "https://google.com" );
8
waitForLoadState( page );
9
expect( page.title() ).toBe( "Google" );
10
} );
11
} );
12
}
13
14
}
15
var page = browser.newPage();
component extends="cbPlaywright.models.PlaywrightTestCase" {
1
2
function run() {
3
describe( "Playwright Tests", () => {
4
it( "can visit the Google homepage", () => {
5
var browser = launchBrowser( variables.playwright.chromium() );
6
7
navigate( page, "https://google.com" );
8
waitForLoadState( page );
9
expect( page.title() ).toBe( "Google" );
10
} );
11
} );
12
}
13
14
}
15
navigate( page, "https://google.com" );
waitForLoadState( page );
component extends="cbPlaywright.models.PlaywrightTestCase" {
1
2
function run() {
3
describe( "Playwright Tests", () => {
4
it( "can visit the Google homepage", () => {
5
var browser = launchBrowser( variables.playwright.chromium() );
6
var page = browser.newPage();
7
8
9
expect( page.title() ).toBe( "Google" );
10
} );
11
} );
12
}
13
14
}
15
expect( page.title() ).toBe( "Google" );
component extends="cbPlaywright.models.PlaywrightTestCase" {
1
2
function run() {
3
describe( "Playwright Tests", () => {
4
it( "can visit the Google homepage", () => {
5
var browser = launchBrowser( variables.playwright.chromium() );
6
var page = browser.newPage();
7
navigate( page, "https://google.com" );
8
waitForLoadState( page );
9
10
} );
11
} );
12
}
13
14
}
15
Visit a Page
component extends="cbPlaywright.models.PlaywrightTestCase" {
function run() {
describe( "Playwright Tests", () => {
it( "can perform a search on Google", () => {
var browser = launchBrowser( variables.playwright.chromium() );
var page = browser.newPage();
navigate( page, "https://google.com" );
waitForLoadState( page );
var searchBox = locateElement( page, '[aria-label="Search"]' );
fill( searchBox, "playwright" );
press( searchBox, "Enter" );
expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" );
} );
} );
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Fill Out a Form
component extends="cbPlaywright.models.PlaywrightTestCase" {
function run() {
describe( "Playwright Tests", () => {
it( "can perform a search on Google", () => {
var browser = launchBrowser( variables.playwright.chromium() );
var page = browser.newPage();
navigate( page, "https://google.com" );
waitForLoadState( page );
var searchBox = locateElement( page, '[aria-label="Search"]' );
fill( searchBox, "playwright" );
press( searchBox, "Enter" );
expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" );
} );
} );
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var searchBox = locateElement( page, '[aria-label="Search"]' );
fill( searchBox, "playwright" );
press( searchBox, "Enter" );
expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" );
component extends="cbPlaywright.models.PlaywrightTestCase" {
1
2
function run() {
3
describe( "Playwright Tests", () => {
4
it( "can perform a search on Google", () => {
5
var browser = launchBrowser( variables.playwright.chromium() );
6
var page = browser.newPage();
7
navigate( page, "https://google.com" );
8
waitForLoadState( page );
9
10
11
12
13
14
15
} );
16
} );
17
}
18
19
}
20
Fill Out a Form
What makes a
good Selector?
Role
Label Text
Placeholder Text
Text
Display Value
What makes a good Selector?
https://testing-library.com/docs/queries/about
1. Queries Accessible
to Everyone
2. Semantic Queries 3. Test IDs
Alt Text
Title
component extends="cbPlaywright.models.PlaywrightTestCase" {
function run() {
describe( "Playwright Tests", () => {
it( "can visit the Google homepage", () => {
var browser = launchBrowser( variables.playwright.chromium() );
var page = browser.newPage();
navigate( page, "https://google.com" );
waitForLoadState( page );
expect( page.title() ).toBe( "Google" );
screenshotPage( page, "/tests/results/homepage.png" );
} );
} );
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Take a Screenshot
component extends="cbPlaywright.models.PlaywrightTestCase" {
function run() {
describe( "Playwright Tests", () => {
it( "can visit the Google homepage", () => {
var browser = launchBrowser( variables.playwright.chromium() );
var page = browser.newPage();
navigate( page, "https://google.com" );
waitForLoadState( page );
expect( page.title() ).toBe( "Google" );
screenshotPage( page, "/tests/results/homepage.png" );
} );
} );
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
screenshotPage( page, "/tests/results/homepage.png" );
component extends="cbPlaywright.models.PlaywrightTestCase" {
1
2
function run() {
3
describe( "Playwright Tests", () => {
4
it( "can visit the Google homepage", () => {
5
var browser = launchBrowser( variables.playwright.chromium() );
6
var page = browser.newPage();
7
navigate( page, "https://google.com" );
8
waitForLoadState( page );
9
expect( page.title() ).toBe( "Google" );
10
11
} );
12
} );
13
}
14
15
}
16
Take a Screenshot
component extends="cbPlaywright.models.PlaywrightTestCase" {
function run() {
describe( "Playwright Tests", () => {
it( "fill out the search form and click a link", () => {
var browser = launchBrowser( variables.playwright.chromium() );
newRecordedContextForBrowser( browser, "/tests/results/videos", ( context ) => {
var page = context.newPage();
navigate( page, "https://google.com" );
waitForLoadState( page );
var searchBox = locateElement( page, '[aria-label="Search"]' );
fill( searchBox, "playwright" );
press( searchBox, "Enter" );
expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" );
click(
locateElement(
page,
"text=Playwright: Fast and reliable end-to-end testing for modern ..."
)
);
waitForUrl( page, "https://playwright.dev/" );
} );
} );
} );
}
}
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
Record a Video
component extends="cbPlaywright.models.PlaywrightTestCase" {
function run() {
describe( "Playwright Tests", () => {
it( "fill out the search form and click a link", () => {
var browser = launchBrowser( variables.playwright.chromium() );
newRecordedContextForBrowser( browser, "/tests/results/videos", ( context ) => {
var page = context.newPage();
navigate( page, "https://google.com" );
waitForLoadState( page );
var searchBox = locateElement( page, '[aria-label="Search"]' );
fill( searchBox, "playwright" );
press( searchBox, "Enter" );
expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" );
click(
locateElement(
page,
"text=Playwright: Fast and reliable end-to-end testing for modern ..."
)
);
waitForUrl( page, "https://playwright.dev/" );
} );
} );
} );
}
}
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
newRecordedContextForBrowser( browser, "/tests/results/videos", ( context ) => {
} );
component extends="cbPlaywright.models.PlaywrightTestCase" {
1
2
function run() {
3
describe( "Playwright Tests", () => {
4
it( "fill out the search form and click a link", () => {
5
var browser = launchBrowser( variables.playwright.chromium() );
6
7
var page = context.newPage();
8
navigate( page, "https://google.com" );
9
waitForLoadState( page );
10
11
var searchBox = locateElement( page, '[aria-label="Search"]' );
12
fill( searchBox, "playwright" );
13
press( searchBox, "Enter" );
14
15
expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" );
16
17
click(
18
locateElement(
19
page,
20
"text=Playwright: Fast and reliable end-to-end testing for modern ..."
21
)
22
);
23
24
waitForUrl( page, "https://playwright.dev/" );
25
26
} );
27
} );
28
}
29
30
}
31
Record a Video
component extends="cbPlaywright.models.PlaywrightTestCase" {
function run() {
describe( "Playwright Tests", () => {
it( "fill out the search form and click a link", () => {
var browser = launchBrowser( variables.playwright.chromium() );
newRecordedContextForBrowser( browser, "/tests/results/videos", ( context ) => {
var page = context.newPage();
navigate( page, "https://google.com" );
waitForLoadState( page );
var searchBox = locateElement( page, '[aria-label="Search"]' );
fill( searchBox, "playwright" );
press( searchBox, "Enter" );
expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" );
click(
locateElement(
page,
"text=Playwright: Fast and reliable end-to-end testing for modern ..."
)
);
waitForUrl( page, "https://playwright.dev/" );
} );
} );
} );
}
}
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
newRecordedContextForBrowser( browser, "/tests/results/videos", ( context ) => {
} );
component extends="cbPlaywright.models.PlaywrightTestCase" {
1
2
function run() {
3
describe( "Playwright Tests", () => {
4
it( "fill out the search form and click a link", () => {
5
var browser = launchBrowser( variables.playwright.chromium() );
6
7
var page = context.newPage();
8
navigate( page, "https://google.com" );
9
waitForLoadState( page );
10
11
var searchBox = locateElement( page, '[aria-label="Search"]' );
12
fill( searchBox, "playwright" );
13
press( searchBox, "Enter" );
14
15
expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" );
16
17
click(
18
locateElement(
19
page,
20
"text=Playwright: Fast and reliable end-to-end testing for modern ..."
21
)
22
);
23
24
waitForUrl( page, "https://playwright.dev/" );
25
26
} );
27
} );
28
}
29
30
}
31
newRecordedContextForBrowser( browser, "/tests/results/videos", ( context ) => {
var page = context.newPage();
} );
component extends="cbPlaywright.models.PlaywrightTestCase" {
1
2
function run() {
3
describe( "Playwright Tests", () => {
4
it( "fill out the search form and click a link", () => {
5
var browser = launchBrowser( variables.playwright.chromium() );
6
7
8
navigate( page, "https://google.com" );
9
waitForLoadState( page );
10
11
var searchBox = locateElement( page, '[aria-label="Search"]' );
12
fill( searchBox, "playwright" );
13
press( searchBox, "Enter" );
14
15
expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" );
16
17
click(
18
locateElement(
19
page,
20
"text=Playwright: Fast and reliable end-to-end testing for modern ..."
21
)
22
);
23
24
waitForUrl( page, "https://playwright.dev/" );
25
26
} );
27
} );
28
}
29
30
}
31
Record a Video
component extends="cbPlaywright.models.PlaywrightTestCase" {
function run() {
describe( "Playwright Tests", () => {
it( "fill out the search form and click a link", () => {
var browser = launchBrowser( variables.playwright.chromium() );
var context = browser.newContext();
traceContext( context, "/tests/results/trace.zip", function() {
var page = context.newPage();
navigate( page, "https://google.com" );
waitForLoadState( page );
var searchBox = locateElement( page, '[aria-label="Search"]' );
fill( searchBox, "playwright" );
press( searchBox, "Enter" );
expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" );
click(
locateElement(
page,
"text=Playwright: Fast and reliable end-to-end testing for modern ..."
)
);
waitForUrl( page, "https://playwright.dev/" );
} );
} );
} );
}
}
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
Save a Trace
component extends="cbPlaywright.models.PlaywrightTestCase" {
function run() {
describe( "Playwright Tests", () => {
it( "fill out the search form and click a link", () => {
var browser = launchBrowser( variables.playwright.chromium() );
var context = browser.newContext();
traceContext( context, "/tests/results/trace.zip", function() {
var page = context.newPage();
navigate( page, "https://google.com" );
waitForLoadState( page );
var searchBox = locateElement( page, '[aria-label="Search"]' );
fill( searchBox, "playwright" );
press( searchBox, "Enter" );
expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" );
click(
locateElement(
page,
"text=Playwright: Fast and reliable end-to-end testing for modern ..."
)
);
waitForUrl( page, "https://playwright.dev/" );
} );
} );
} );
}
}
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
var page = context.newPage();
} );
component extends="cbPlaywright.models.PlaywrightTestCase" {
1
function run() {
2
describe( "Playwright Tests", () => {
3
it( "fill out the search form and click a link", () => {
4
var browser = launchBrowser( variables.playwright.chromium() );
5
var context = browser.newContext();
6
traceContext( context, "/tests/results/trace.zip", function() {
7
8
navigate( page, "https://google.com" );
9
waitForLoadState( page );
10
11
var searchBox = locateElement( page, '[aria-label="Search"]' );
12
fill( searchBox, "playwright" );
13
press( searchBox, "Enter" );
14
15
expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" );
16
17
click(
18
locateElement(
19
page,
20
"text=Playwright: Fast and reliable end-to-end testing for modern ..."
21
)
22
);
23
24
waitForUrl( page, "https://playwright.dev/" );
25
} );
26
27
} );
28
}
29
}
30
Save a Trace
Save a Trace
Demo
Bonus
name: PRs and Branches
on:
- push
jobs:
tests:
runs-on: ubuntu-latest
name: Tests
steps:
- name: Checkout Repository
uses: actions/checkout@v2
- name: Setup Java JDK
uses: actions/setup-java@v1.4.3
with:
java-version: 11
- name: Set Up CommandBox
uses: elpete/setup-commandbox@v1.0.0
- name: Install dependencies
run: box install
- name: Start server
run: box server start
- name: Install Playwright dependencies
run: |
box playwright-cli install-deps
box playwright-cli install chromium
- name: Run TestBox Tests
run: box testbox run
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
GitHub Actions
name: PRs and Branches
on:
- push
jobs:
tests:
runs-on: ubuntu-latest
name: Tests
steps:
- name: Checkout Repository
uses: actions/checkout@v2
- name: Setup Java JDK
uses: actions/setup-java@v1.4.3
with:
java-version: 11
- name: Set Up CommandBox
uses: elpete/setup-commandbox@v1.0.0
- name: Install dependencies
run: box install
- name: Start server
run: box server start
- name: Install Playwright dependencies
run: |
box playwright-cli install-deps
box playwright-cli install chromium
- name: Run TestBox Tests
run: box testbox run
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
- name: Checkout Repository
name: PRs and Branches
1
2
on:
3
- push
4
5
jobs:
6
tests:
7
runs-on: ubuntu-latest
8
name: Tests
9
steps:
10
11
uses: actions/checkout@v2
12
13
- name: Setup Java JDK
14
uses: actions/setup-java@v1.4.3
15
with:
16
java-version: 11
17
18
- name: Set Up CommandBox
19
uses: elpete/setup-commandbox@v1.0.0
20
21
- name: Install dependencies
22
run: box install
23
24
- name: Start server
25
run: box server start
26
27
- name: Install Playwright dependencies
28
run: |
29
box playwright-cli install-deps
30
box playwright-cli install chromium
31
32
- name: Run TestBox Tests
33
run: box testbox run
34
GitHub Actions
ITB 2023 cbPlaywright End-to-end Tests with Playwright and TestBox - Eric Petersen.pdf

More Related Content

Similar to ITB 2023 cbPlaywright End-to-end Tests with Playwright and TestBox - Eric Petersen.pdf (20)

PDF
Playwright For Test Automation _ A Step by Step Guide.pdf
Steve Wortham
 
PDF
Getting Started with Playwright: A Beginner-Friendly Introduction & Setup Guide
Shubham Joshi
 
PDF
Playwright: An Emerging Tool in Test Automation
Anna Royzman
 
PDF
Writing Maintainable Playwright Tests with Ease
Shubham Joshi
 
PDF
Leveraging Playwright for API Testing.pdf
Steve Wortham
 
PPTX
QA or the Highway 2022.pptx
Perfecto Mobile
 
PPTX
PlayWright Training - PlayWright Automation Training.pptx
himavanthvisualpath
 
PPTX
Building Robust Web Applications with Test-Driven Development and Playwright:...
Maurice De Beijer [MVP]
 
PPTX
Playwright Online Training | Playwright Automation Testing Hyderabad
Jayanthvisualpath
 
PPTX
UI Test Automation With Playwright with Pytest
Arshad QA
 
PDF
Playwright vs. Jest_ A Comprehensive Guide to Choosing the Right Testing Fram...
kalichargn70th171
 
PPTX
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 
PPTX
Dev Day 2024: Jonathan Frere - Playwright: Das Beste aus dem Dramatiker herau...
emmaberlin1
 
PDF
No drama here - E2E-testing django with playwright
Mastacheata1
 
PDF
playwrithgttttttttttttttttttttttSlides.pdf
SarvjeetKumarSingh1
 
PDF
Cypress vs Playwright: A Comparative Analysis
Shubham Joshi
 
PDF
Guide to Playwright Debugging – Tips and Techniques.pdf
Steve Wortham
 
PPTX
Browser Automation with Playwright – for integration, RPA, UI testing and mor...
Lucas Jellema
 
PDF
KrishnaToolComparisionPPT.pdf
QA or the Highway
 
PPTX
ОЛЕКСІЙ ОСТАПОВ «Найкрутіші особливості автоматизації на Playwright Python» K...
QADay
 
Playwright For Test Automation _ A Step by Step Guide.pdf
Steve Wortham
 
Getting Started with Playwright: A Beginner-Friendly Introduction & Setup Guide
Shubham Joshi
 
Playwright: An Emerging Tool in Test Automation
Anna Royzman
 
Writing Maintainable Playwright Tests with Ease
Shubham Joshi
 
Leveraging Playwright for API Testing.pdf
Steve Wortham
 
QA or the Highway 2022.pptx
Perfecto Mobile
 
PlayWright Training - PlayWright Automation Training.pptx
himavanthvisualpath
 
Building Robust Web Applications with Test-Driven Development and Playwright:...
Maurice De Beijer [MVP]
 
Playwright Online Training | Playwright Automation Testing Hyderabad
Jayanthvisualpath
 
UI Test Automation With Playwright with Pytest
Arshad QA
 
Playwright vs. Jest_ A Comprehensive Guide to Choosing the Right Testing Fram...
kalichargn70th171
 
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 
Dev Day 2024: Jonathan Frere - Playwright: Das Beste aus dem Dramatiker herau...
emmaberlin1
 
No drama here - E2E-testing django with playwright
Mastacheata1
 
playwrithgttttttttttttttttttttttSlides.pdf
SarvjeetKumarSingh1
 
Cypress vs Playwright: A Comparative Analysis
Shubham Joshi
 
Guide to Playwright Debugging – Tips and Techniques.pdf
Steve Wortham
 
Browser Automation with Playwright – for integration, RPA, UI testing and mor...
Lucas Jellema
 
KrishnaToolComparisionPPT.pdf
QA or the Highway
 
ОЛЕКСІЙ ОСТАПОВ «Найкрутіші особливості автоматизації на Playwright Python» K...
QADay
 

More from Ortus Solutions, Corp (20)

PDF
TheFutureIsDynamic-BoxLang witch Luis Majano.pdf
Ortus Solutions, Corp
 
PDF
June Webinar: BoxLang-Dynamic-AWS-Lambda
Ortus Solutions, Corp
 
PDF
BoxLang-Dynamic-AWS-Lambda by Luis Majano.pdf
Ortus Solutions, Corp
 
PDF
What's-New-with-BoxLang-Brad Wood.pptx.pdf
Ortus Solutions, Corp
 
PDF
Getting Started with BoxLang - CFCamp 2025.pdf
Ortus Solutions, Corp
 
PDF
CFCamp2025 - Keynote Day 1 led by Luis Majano.pdf
Ortus Solutions, Corp
 
PDF
What's New with BoxLang Led by Brad Wood.pdf
Ortus Solutions, Corp
 
PDF
Vector Databases and the BoxLangCFML Developer.pdf
Ortus Solutions, Corp
 
PDF
Using cbSSO in a ColdBox App Led by Jacob Beers.pdf
Ortus Solutions, Corp
 
PDF
Use JSON to Slash Your Database Performance.pdf
Ortus Solutions, Corp
 
PDF
Portable CI wGitLab and Github led by Gavin Pickin.pdf
Ortus Solutions, Corp
 
PDF
Tame the Mesh An intro to cross-platform tracing and troubleshooting.pdf
Ortus Solutions, Corp
 
PDF
Supercharging CommandBox with Let's Encrypt.pdf
Ortus Solutions, Corp
 
PDF
Spice up your site with cool animations using GSAP..pdf
Ortus Solutions, Corp
 
PDF
Passkeys and cbSecurity Led by Eric Peterson.pdf
Ortus Solutions, Corp
 
PDF
Legacy Code Nightmares , Hellscapes, and Lessons Learned.pdf
Ortus Solutions, Corp
 
PDF
Integrating the OpenAI API in Your Coldfusion Apps.pdf
Ortus Solutions, Corp
 
PDF
Hidden Gems in FusionReactor for BoxLang, ACF, and Lucee Users.pdf
Ortus Solutions, Corp
 
PDF
Geting-started with BoxLang Led By Raymon Camden.pdf
Ortus Solutions, Corp
 
PDF
From Zero to CRUD with ORM - Led by Annette Liskey.pdf
Ortus Solutions, Corp
 
TheFutureIsDynamic-BoxLang witch Luis Majano.pdf
Ortus Solutions, Corp
 
June Webinar: BoxLang-Dynamic-AWS-Lambda
Ortus Solutions, Corp
 
BoxLang-Dynamic-AWS-Lambda by Luis Majano.pdf
Ortus Solutions, Corp
 
What's-New-with-BoxLang-Brad Wood.pptx.pdf
Ortus Solutions, Corp
 
Getting Started with BoxLang - CFCamp 2025.pdf
Ortus Solutions, Corp
 
CFCamp2025 - Keynote Day 1 led by Luis Majano.pdf
Ortus Solutions, Corp
 
What's New with BoxLang Led by Brad Wood.pdf
Ortus Solutions, Corp
 
Vector Databases and the BoxLangCFML Developer.pdf
Ortus Solutions, Corp
 
Using cbSSO in a ColdBox App Led by Jacob Beers.pdf
Ortus Solutions, Corp
 
Use JSON to Slash Your Database Performance.pdf
Ortus Solutions, Corp
 
Portable CI wGitLab and Github led by Gavin Pickin.pdf
Ortus Solutions, Corp
 
Tame the Mesh An intro to cross-platform tracing and troubleshooting.pdf
Ortus Solutions, Corp
 
Supercharging CommandBox with Let's Encrypt.pdf
Ortus Solutions, Corp
 
Spice up your site with cool animations using GSAP..pdf
Ortus Solutions, Corp
 
Passkeys and cbSecurity Led by Eric Peterson.pdf
Ortus Solutions, Corp
 
Legacy Code Nightmares , Hellscapes, and Lessons Learned.pdf
Ortus Solutions, Corp
 
Integrating the OpenAI API in Your Coldfusion Apps.pdf
Ortus Solutions, Corp
 
Hidden Gems in FusionReactor for BoxLang, ACF, and Lucee Users.pdf
Ortus Solutions, Corp
 
Geting-started with BoxLang Led By Raymon Camden.pdf
Ortus Solutions, Corp
 
From Zero to CRUD with ORM - Led by Annette Liskey.pdf
Ortus Solutions, Corp
 
Ad

Recently uploaded (20)

PDF
Thread In Android-Mastering Concurrency for Responsive Apps.pdf
Nabin Dhakal
 
PPTX
Agentic Automation: Build & Deploy Your First UiPath Agent
klpathrudu
 
PDF
iTop VPN With Crack Lifetime Activation Key-CODE
utfefguu
 
PDF
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
PPTX
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
PPTX
Tally software_Introduction_Presentation
AditiBansal54083
 
PDF
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
PDF
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
PPTX
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
PPTX
In From the Cold: Open Source as Part of Mainstream Software Asset Management
Shane Coughlan
 
PDF
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
PDF
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
PPTX
Empowering Asian Contributions: The Rise of Regional User Groups in Open Sour...
Shane Coughlan
 
PDF
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pdf
Varsha Nayak
 
PDF
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
 
PPTX
Agentic Automation Journey Series Day 2 – Prompt Engineering for UiPath Agents
klpathrudu
 
PDF
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
PDF
유니티에서 Burst Compiler+ThreadedJobs+SIMD 적용사례
Seongdae Kim
 
PDF
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
Thread In Android-Mastering Concurrency for Responsive Apps.pdf
Nabin Dhakal
 
Agentic Automation: Build & Deploy Your First UiPath Agent
klpathrudu
 
iTop VPN With Crack Lifetime Activation Key-CODE
utfefguu
 
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
Tally software_Introduction_Presentation
AditiBansal54083
 
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
In From the Cold: Open Source as Part of Mainstream Software Asset Management
Shane Coughlan
 
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
Empowering Asian Contributions: The Rise of Regional User Groups in Open Sour...
Shane Coughlan
 
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pdf
Varsha Nayak
 
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
 
Agentic Automation Journey Series Day 2 – Prompt Engineering for UiPath Agents
klpathrudu
 
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
유니티에서 Burst Compiler+ThreadedJobs+SIMD 적용사례
Seongdae Kim
 
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
Ad

ITB 2023 cbPlaywright End-to-end Tests with Playwright and TestBox - Eric Petersen.pdf

  • 3. What this talk is An overview of cbPlaywright An overview of Playwright Java How to use the companion CommandBox library A few end-to-end testing selector strategies Live coding cbPlaywright tests
  • 4. What this talk isn't About unit, integration, or any other kind of testing besides end-to-end (or browser) tests Comparison to other end-to-end testing tools Deep dive into end-to-end testing best practices
  • 7. Includes the necessary jars and drivers to run Playwright Java Provides integration with TestBox and ColdBox tests Helper methods for making interacting with Playwright Java easier What is cbPlaywright?
  • 10. If Playwright Java exists...why would I use cbPlaywright?
  • 11. Includes the necessary jars to run Playwright Java
  • 12. Companion CommandBox module for downloading the correct platform drivers
  • 13. Helper functions to turn this.... var screenshotOptions = createObject( "java", "com.microsoft.playwright.Page$ScreenshotOptions" ).init(); var screenshotPath = createObject( "java", "java.nio.file.Paths" ).get( javacast( "String", expandPath( "/tests/results/screenshotOne.png" ) ), javacast( "String[]", [] ) ); screenshotOptions.setPath( screenshotPath ); page.screenshot( screenshotOptions ); 1 2 3 4 5 6 ...into this screenshotPage( page, "/tests/results/screenshotOne.png" ); 1
  • 16. Unfortunately, there is more this time....
  • 17. There's this thing called a driver.... Running the driver from the Playwright Java jars was finicky The driver-bundle jar is very large (about 200 MB unzipped) The driver-bundle included versions for all the platforms You ended up downloading a full driver-bundle for every cbPlaywright installation. Interacting with the driver CLI was a pain
  • 19. CommandBox cbPlaywright Installs as a dependency of cbPlaywright Manages installing the correct driver for your platform Automatically downloads a driver on install Provides a passthrough to the Playwright CLI # Install the Playwright driver cbplaywright driver install # Install Chromium as a test browser playwright install chromium 1 2 3 4 5
  • 21. // tests/Application.cfc component { this.javaSettings = { loadPaths: directoryList( rootPath & "modules/cbPlaywright/lib", true, "array", "*jar" ), loadColdFusionClassPath: true, reloadOnChange: false }; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Add the Jar Paths
  • 22. // tests/Application.cfc component { this.mappings[ "/cbPlaywright" ] = rootPath & "/modules/cbPlaywright"; } 1 2 3 4 5 6 Create a Mapping
  • 24. Usage
  • 26. component extends="cbPlaywright.models.PlaywrightTestCase" { function run() { // ... } } 1 2 3 4 5 6 7 Extend the Playwright Test Case component extends="cbPlaywright.models.ColdBoxPlaywrightTestCase" { function run() { // ... } } 1 2 3 4 5 6 7
  • 27. component extends="cbPlaywright.models.PlaywrightTestCase" { function run() { describe( "Playwright Tests", () => { it( "can visit the Google homepage", () => { var browser = launchBrowser( variables.playwright.chromium() ); var page = browser.newPage(); navigate( page, "https://google.com" ); waitForLoadState( page ); expect( page.title() ).toBe( "Google" ); } ); } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Visit a Page
  • 28. component extends="cbPlaywright.models.PlaywrightTestCase" { function run() { describe( "Playwright Tests", () => { it( "can visit the Google homepage", () => { var browser = launchBrowser( variables.playwright.chromium() ); var page = browser.newPage(); navigate( page, "https://google.com" ); waitForLoadState( page ); expect( page.title() ).toBe( "Google" ); } ); } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var browser = launchBrowser( variables.playwright.chromium() ); component extends="cbPlaywright.models.PlaywrightTestCase" { 1 2 function run() { 3 describe( "Playwright Tests", () => { 4 it( "can visit the Google homepage", () => { 5 6 var page = browser.newPage(); 7 navigate( page, "https://google.com" ); 8 waitForLoadState( page ); 9 expect( page.title() ).toBe( "Google" ); 10 } ); 11 } ); 12 } 13 14 } 15 Visit a Page
  • 29. component extends="cbPlaywright.models.PlaywrightTestCase" { function run() { describe( "Playwright Tests", () => { it( "can visit the Google homepage", () => { var browser = launchBrowser( variables.playwright.chromium() ); var page = browser.newPage(); navigate( page, "https://google.com" ); waitForLoadState( page ); expect( page.title() ).toBe( "Google" ); } ); } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var browser = launchBrowser( variables.playwright.chromium() ); component extends="cbPlaywright.models.PlaywrightTestCase" { 1 2 function run() { 3 describe( "Playwright Tests", () => { 4 it( "can visit the Google homepage", () => { 5 6 var page = browser.newPage(); 7 navigate( page, "https://google.com" ); 8 waitForLoadState( page ); 9 expect( page.title() ).toBe( "Google" ); 10 } ); 11 } ); 12 } 13 14 } 15 var page = browser.newPage(); component extends="cbPlaywright.models.PlaywrightTestCase" { 1 2 function run() { 3 describe( "Playwright Tests", () => { 4 it( "can visit the Google homepage", () => { 5 var browser = launchBrowser( variables.playwright.chromium() ); 6 7 navigate( page, "https://google.com" ); 8 waitForLoadState( page ); 9 expect( page.title() ).toBe( "Google" ); 10 } ); 11 } ); 12 } 13 14 } 15 Visit a Page
  • 30. component extends="cbPlaywright.models.PlaywrightTestCase" { function run() { describe( "Playwright Tests", () => { it( "can visit the Google homepage", () => { var browser = launchBrowser( variables.playwright.chromium() ); var page = browser.newPage(); navigate( page, "https://google.com" ); waitForLoadState( page ); expect( page.title() ).toBe( "Google" ); } ); } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var browser = launchBrowser( variables.playwright.chromium() ); component extends="cbPlaywright.models.PlaywrightTestCase" { 1 2 function run() { 3 describe( "Playwright Tests", () => { 4 it( "can visit the Google homepage", () => { 5 6 var page = browser.newPage(); 7 navigate( page, "https://google.com" ); 8 waitForLoadState( page ); 9 expect( page.title() ).toBe( "Google" ); 10 } ); 11 } ); 12 } 13 14 } 15 var page = browser.newPage(); component extends="cbPlaywright.models.PlaywrightTestCase" { 1 2 function run() { 3 describe( "Playwright Tests", () => { 4 it( "can visit the Google homepage", () => { 5 var browser = launchBrowser( variables.playwright.chromium() ); 6 7 navigate( page, "https://google.com" ); 8 waitForLoadState( page ); 9 expect( page.title() ).toBe( "Google" ); 10 } ); 11 } ); 12 } 13 14 } 15 navigate( page, "https://google.com" ); waitForLoadState( page ); component extends="cbPlaywright.models.PlaywrightTestCase" { 1 2 function run() { 3 describe( "Playwright Tests", () => { 4 it( "can visit the Google homepage", () => { 5 var browser = launchBrowser( variables.playwright.chromium() ); 6 var page = browser.newPage(); 7 8 9 expect( page.title() ).toBe( "Google" ); 10 } ); 11 } ); 12 } 13 14 } 15 Visit a Page
  • 31. component extends="cbPlaywright.models.PlaywrightTestCase" { function run() { describe( "Playwright Tests", () => { it( "can visit the Google homepage", () => { var browser = launchBrowser( variables.playwright.chromium() ); var page = browser.newPage(); navigate( page, "https://google.com" ); waitForLoadState( page ); expect( page.title() ).toBe( "Google" ); } ); } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var browser = launchBrowser( variables.playwright.chromium() ); component extends="cbPlaywright.models.PlaywrightTestCase" { 1 2 function run() { 3 describe( "Playwright Tests", () => { 4 it( "can visit the Google homepage", () => { 5 6 var page = browser.newPage(); 7 navigate( page, "https://google.com" ); 8 waitForLoadState( page ); 9 expect( page.title() ).toBe( "Google" ); 10 } ); 11 } ); 12 } 13 14 } 15 var page = browser.newPage(); component extends="cbPlaywright.models.PlaywrightTestCase" { 1 2 function run() { 3 describe( "Playwright Tests", () => { 4 it( "can visit the Google homepage", () => { 5 var browser = launchBrowser( variables.playwright.chromium() ); 6 7 navigate( page, "https://google.com" ); 8 waitForLoadState( page ); 9 expect( page.title() ).toBe( "Google" ); 10 } ); 11 } ); 12 } 13 14 } 15 navigate( page, "https://google.com" ); waitForLoadState( page ); component extends="cbPlaywright.models.PlaywrightTestCase" { 1 2 function run() { 3 describe( "Playwright Tests", () => { 4 it( "can visit the Google homepage", () => { 5 var browser = launchBrowser( variables.playwright.chromium() ); 6 var page = browser.newPage(); 7 8 9 expect( page.title() ).toBe( "Google" ); 10 } ); 11 } ); 12 } 13 14 } 15 expect( page.title() ).toBe( "Google" ); component extends="cbPlaywright.models.PlaywrightTestCase" { 1 2 function run() { 3 describe( "Playwright Tests", () => { 4 it( "can visit the Google homepage", () => { 5 var browser = launchBrowser( variables.playwright.chromium() ); 6 var page = browser.newPage(); 7 navigate( page, "https://google.com" ); 8 waitForLoadState( page ); 9 10 } ); 11 } ); 12 } 13 14 } 15 Visit a Page
  • 32. component extends="cbPlaywright.models.PlaywrightTestCase" { function run() { describe( "Playwright Tests", () => { it( "can perform a search on Google", () => { var browser = launchBrowser( variables.playwright.chromium() ); var page = browser.newPage(); navigate( page, "https://google.com" ); waitForLoadState( page ); var searchBox = locateElement( page, '[aria-label="Search"]' ); fill( searchBox, "playwright" ); press( searchBox, "Enter" ); expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" ); } ); } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Fill Out a Form
  • 33. component extends="cbPlaywright.models.PlaywrightTestCase" { function run() { describe( "Playwright Tests", () => { it( "can perform a search on Google", () => { var browser = launchBrowser( variables.playwright.chromium() ); var page = browser.newPage(); navigate( page, "https://google.com" ); waitForLoadState( page ); var searchBox = locateElement( page, '[aria-label="Search"]' ); fill( searchBox, "playwright" ); press( searchBox, "Enter" ); expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" ); } ); } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 var searchBox = locateElement( page, '[aria-label="Search"]' ); fill( searchBox, "playwright" ); press( searchBox, "Enter" ); expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" ); component extends="cbPlaywright.models.PlaywrightTestCase" { 1 2 function run() { 3 describe( "Playwright Tests", () => { 4 it( "can perform a search on Google", () => { 5 var browser = launchBrowser( variables.playwright.chromium() ); 6 var page = browser.newPage(); 7 navigate( page, "https://google.com" ); 8 waitForLoadState( page ); 9 10 11 12 13 14 15 } ); 16 } ); 17 } 18 19 } 20 Fill Out a Form
  • 34. What makes a good Selector?
  • 35. Role Label Text Placeholder Text Text Display Value What makes a good Selector? https://testing-library.com/docs/queries/about 1. Queries Accessible to Everyone 2. Semantic Queries 3. Test IDs Alt Text Title
  • 36. component extends="cbPlaywright.models.PlaywrightTestCase" { function run() { describe( "Playwright Tests", () => { it( "can visit the Google homepage", () => { var browser = launchBrowser( variables.playwright.chromium() ); var page = browser.newPage(); navigate( page, "https://google.com" ); waitForLoadState( page ); expect( page.title() ).toBe( "Google" ); screenshotPage( page, "/tests/results/homepage.png" ); } ); } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Take a Screenshot
  • 37. component extends="cbPlaywright.models.PlaywrightTestCase" { function run() { describe( "Playwright Tests", () => { it( "can visit the Google homepage", () => { var browser = launchBrowser( variables.playwright.chromium() ); var page = browser.newPage(); navigate( page, "https://google.com" ); waitForLoadState( page ); expect( page.title() ).toBe( "Google" ); screenshotPage( page, "/tests/results/homepage.png" ); } ); } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 screenshotPage( page, "/tests/results/homepage.png" ); component extends="cbPlaywright.models.PlaywrightTestCase" { 1 2 function run() { 3 describe( "Playwright Tests", () => { 4 it( "can visit the Google homepage", () => { 5 var browser = launchBrowser( variables.playwright.chromium() ); 6 var page = browser.newPage(); 7 navigate( page, "https://google.com" ); 8 waitForLoadState( page ); 9 expect( page.title() ).toBe( "Google" ); 10 11 } ); 12 } ); 13 } 14 15 } 16 Take a Screenshot
  • 38. component extends="cbPlaywright.models.PlaywrightTestCase" { function run() { describe( "Playwright Tests", () => { it( "fill out the search form and click a link", () => { var browser = launchBrowser( variables.playwright.chromium() ); newRecordedContextForBrowser( browser, "/tests/results/videos", ( context ) => { var page = context.newPage(); navigate( page, "https://google.com" ); waitForLoadState( page ); var searchBox = locateElement( page, '[aria-label="Search"]' ); fill( searchBox, "playwright" ); press( searchBox, "Enter" ); expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" ); click( locateElement( page, "text=Playwright: Fast and reliable end-to-end testing for modern ..." ) ); waitForUrl( page, "https://playwright.dev/" ); } ); } ); } ); } } 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 Record a Video
  • 39. component extends="cbPlaywright.models.PlaywrightTestCase" { function run() { describe( "Playwright Tests", () => { it( "fill out the search form and click a link", () => { var browser = launchBrowser( variables.playwright.chromium() ); newRecordedContextForBrowser( browser, "/tests/results/videos", ( context ) => { var page = context.newPage(); navigate( page, "https://google.com" ); waitForLoadState( page ); var searchBox = locateElement( page, '[aria-label="Search"]' ); fill( searchBox, "playwright" ); press( searchBox, "Enter" ); expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" ); click( locateElement( page, "text=Playwright: Fast and reliable end-to-end testing for modern ..." ) ); waitForUrl( page, "https://playwright.dev/" ); } ); } ); } ); } } 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 newRecordedContextForBrowser( browser, "/tests/results/videos", ( context ) => { } ); component extends="cbPlaywright.models.PlaywrightTestCase" { 1 2 function run() { 3 describe( "Playwright Tests", () => { 4 it( "fill out the search form and click a link", () => { 5 var browser = launchBrowser( variables.playwright.chromium() ); 6 7 var page = context.newPage(); 8 navigate( page, "https://google.com" ); 9 waitForLoadState( page ); 10 11 var searchBox = locateElement( page, '[aria-label="Search"]' ); 12 fill( searchBox, "playwright" ); 13 press( searchBox, "Enter" ); 14 15 expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" ); 16 17 click( 18 locateElement( 19 page, 20 "text=Playwright: Fast and reliable end-to-end testing for modern ..." 21 ) 22 ); 23 24 waitForUrl( page, "https://playwright.dev/" ); 25 26 } ); 27 } ); 28 } 29 30 } 31 Record a Video
  • 40. component extends="cbPlaywright.models.PlaywrightTestCase" { function run() { describe( "Playwright Tests", () => { it( "fill out the search form and click a link", () => { var browser = launchBrowser( variables.playwright.chromium() ); newRecordedContextForBrowser( browser, "/tests/results/videos", ( context ) => { var page = context.newPage(); navigate( page, "https://google.com" ); waitForLoadState( page ); var searchBox = locateElement( page, '[aria-label="Search"]' ); fill( searchBox, "playwright" ); press( searchBox, "Enter" ); expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" ); click( locateElement( page, "text=Playwright: Fast and reliable end-to-end testing for modern ..." ) ); waitForUrl( page, "https://playwright.dev/" ); } ); } ); } ); } } 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 newRecordedContextForBrowser( browser, "/tests/results/videos", ( context ) => { } ); component extends="cbPlaywright.models.PlaywrightTestCase" { 1 2 function run() { 3 describe( "Playwright Tests", () => { 4 it( "fill out the search form and click a link", () => { 5 var browser = launchBrowser( variables.playwright.chromium() ); 6 7 var page = context.newPage(); 8 navigate( page, "https://google.com" ); 9 waitForLoadState( page ); 10 11 var searchBox = locateElement( page, '[aria-label="Search"]' ); 12 fill( searchBox, "playwright" ); 13 press( searchBox, "Enter" ); 14 15 expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" ); 16 17 click( 18 locateElement( 19 page, 20 "text=Playwright: Fast and reliable end-to-end testing for modern ..." 21 ) 22 ); 23 24 waitForUrl( page, "https://playwright.dev/" ); 25 26 } ); 27 } ); 28 } 29 30 } 31 newRecordedContextForBrowser( browser, "/tests/results/videos", ( context ) => { var page = context.newPage(); } ); component extends="cbPlaywright.models.PlaywrightTestCase" { 1 2 function run() { 3 describe( "Playwright Tests", () => { 4 it( "fill out the search form and click a link", () => { 5 var browser = launchBrowser( variables.playwright.chromium() ); 6 7 8 navigate( page, "https://google.com" ); 9 waitForLoadState( page ); 10 11 var searchBox = locateElement( page, '[aria-label="Search"]' ); 12 fill( searchBox, "playwright" ); 13 press( searchBox, "Enter" ); 14 15 expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" ); 16 17 click( 18 locateElement( 19 page, 20 "text=Playwright: Fast and reliable end-to-end testing for modern ..." 21 ) 22 ); 23 24 waitForUrl( page, "https://playwright.dev/" ); 25 26 } ); 27 } ); 28 } 29 30 } 31 Record a Video
  • 41. component extends="cbPlaywright.models.PlaywrightTestCase" { function run() { describe( "Playwright Tests", () => { it( "fill out the search form and click a link", () => { var browser = launchBrowser( variables.playwright.chromium() ); var context = browser.newContext(); traceContext( context, "/tests/results/trace.zip", function() { var page = context.newPage(); navigate( page, "https://google.com" ); waitForLoadState( page ); var searchBox = locateElement( page, '[aria-label="Search"]' ); fill( searchBox, "playwright" ); press( searchBox, "Enter" ); expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" ); click( locateElement( page, "text=Playwright: Fast and reliable end-to-end testing for modern ..." ) ); waitForUrl( page, "https://playwright.dev/" ); } ); } ); } ); } } 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 Save a Trace
  • 42. component extends="cbPlaywright.models.PlaywrightTestCase" { function run() { describe( "Playwright Tests", () => { it( "fill out the search form and click a link", () => { var browser = launchBrowser( variables.playwright.chromium() ); var context = browser.newContext(); traceContext( context, "/tests/results/trace.zip", function() { var page = context.newPage(); navigate( page, "https://google.com" ); waitForLoadState( page ); var searchBox = locateElement( page, '[aria-label="Search"]' ); fill( searchBox, "playwright" ); press( searchBox, "Enter" ); expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" ); click( locateElement( page, "text=Playwright: Fast and reliable end-to-end testing for modern ..." ) ); waitForUrl( page, "https://playwright.dev/" ); } ); } ); } ); } } 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 var page = context.newPage(); } ); component extends="cbPlaywright.models.PlaywrightTestCase" { 1 function run() { 2 describe( "Playwright Tests", () => { 3 it( "fill out the search form and click a link", () => { 4 var browser = launchBrowser( variables.playwright.chromium() ); 5 var context = browser.newContext(); 6 traceContext( context, "/tests/results/trace.zip", function() { 7 8 navigate( page, "https://google.com" ); 9 waitForLoadState( page ); 10 11 var searchBox = locateElement( page, '[aria-label="Search"]' ); 12 fill( searchBox, "playwright" ); 13 press( searchBox, "Enter" ); 14 15 expect( page.url() ).toInclude( "https://www.google.com/search?q=playwright" ); 16 17 click( 18 locateElement( 19 page, 20 "text=Playwright: Fast and reliable end-to-end testing for modern ..." 21 ) 22 ); 23 24 waitForUrl( page, "https://playwright.dev/" ); 25 } ); 26 27 } ); 28 } 29 } 30 Save a Trace
  • 44. Demo
  • 45. Bonus
  • 46. name: PRs and Branches on: - push jobs: tests: runs-on: ubuntu-latest name: Tests steps: - name: Checkout Repository uses: actions/checkout@v2 - name: Setup Java JDK uses: actions/[email protected] with: java-version: 11 - name: Set Up CommandBox uses: elpete/[email protected] - name: Install dependencies run: box install - name: Start server run: box server start - name: Install Playwright dependencies run: | box playwright-cli install-deps box playwright-cli install chromium - name: Run TestBox Tests run: box testbox run 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 GitHub Actions
  • 47. name: PRs and Branches on: - push jobs: tests: runs-on: ubuntu-latest name: Tests steps: - name: Checkout Repository uses: actions/checkout@v2 - name: Setup Java JDK uses: actions/[email protected] with: java-version: 11 - name: Set Up CommandBox uses: elpete/[email protected] - name: Install dependencies run: box install - name: Start server run: box server start - name: Install Playwright dependencies run: | box playwright-cli install-deps box playwright-cli install chromium - name: Run TestBox Tests run: box testbox run 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 - name: Checkout Repository name: PRs and Branches 1 2 on: 3 - push 4 5 jobs: 6 tests: 7 runs-on: ubuntu-latest 8 name: Tests 9 steps: 10 11 uses: actions/checkout@v2 12 13 - name: Setup Java JDK 14 uses: actions/[email protected] 15 with: 16 java-version: 11 17 18 - name: Set Up CommandBox 19 uses: elpete/[email protected] 20 21 - name: Install dependencies 22 run: box install 23 24 - name: Start server 25 run: box server start 26 27 - name: Install Playwright dependencies 28 run: | 29 box playwright-cli install-deps 30 box playwright-cli install chromium 31 32 - name: Run TestBox Tests 33 run: box testbox run 34 GitHub Actions