Supercharge your Playwright tests with AI

ZeroStep's ai() function unlocks the power of GPT3.5 and GPT4 to make Playwright tests simpler and more resilient to change.
Get started
npm i @zerostep/playwright -D

So long, selectors

Instead of CSS selectors or XPath locators, ZeroStep's AI assistant determines what actions to take at runtime based on your plain-text instructions.

Since ZeroStep integrates directly into Playwright, you can incorporate AI into as few or as many tests as you'd like, without changing your development workflow.

ZeroStep AI Prompt
ai("Fill out the form with realistic values")
System under test
Jane
Doe
123 Any St
Philadelphia
PA
https://www.example.com

Write E2E tests that are resilient to change

Script complex interactions and assertions using plain-text instructions

Book the next available timeslot
Search and verify the first organic search result
Create an Opportunity in Salesforce
Get the latest stock price
View article history and verify earliest revision
Go to section and verify ad is displayed
Verify the number of labels in a repo
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import { test, expect } from '@playwright/test'
import { ai } from '@zerostep/playwright'

test.describe('Calendly', () => {
  test('book the next available timeslot', async ({ page }) => {
    await page.goto('https://calendly.com/zerostep-test/test-calendly')

    await ai('Verify that a calendar is displayed', { page, test })
    await ai('Dismiss the privacy modal', { page, test })
    await ai('Click on the first day in the month with times available', { page, test })
    await ai('Click on the first available time in the sidebar', { page, test })
    await ai('Click the Next button', { page, test })
    await ai('Fill out the form with realistic values', { page, test })
    await ai('Submit the form', { page, test })

    const element = await page.getByText('You are scheduled')
    expect(element).toBeDefined()
  })
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import { test, expect } from '@playwright/test'
import { ai } from '@zerostep/playwright'

test.describe('Google', () => {
  const searchTerm = 'software testing'

  test('search and verify the first organic search result', async ({ page }) => {
    await page.goto('https://www.google.com')
    await ai(`Search for '${searchTerm}'`, { page, test })
    await ai('Hit enter', { page, test })

    await page.waitForURL('https://www.google.com/search**')

    const title = await ai(`What is the title of the first organic search result?`, { page, test })

    console.log('First organic search result is: ', title)
  })
})
 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
import { test, expect } from '@playwright/test'
import { ai } from '@zerostep/playwright'

// Replace these values with your Salesforce credentials
const email = 'test@example.com'
const password = 'passwordhere'
const hostname = 'realhostnamehere.develop.lightning.force.com'

test.describe('Salesforce', () => {
  test('create an opportunity', async ({ page }) => {
    await page.goto('https://login.salesforce.com')
    await ai(`Enter the username ${email}`, { page, test })
    await ai(`Enter the password ${password}`, { page, test })
    await page.click('text="Log In"')

    // Only reaches here if we are successfully authenticated
    await page.waitForSelector('text="Home"')

    // Navigate directly to Sales app
    await page.goto(`https://${hostname}/lightning/page/home`)
    await page.waitForSelector('text="Quarterly Performance"')

    await ai('Click on Opportunities link', { page, test })
    await page.click('text="New"')

    // Wait for 'New Opportunity' form to be displayed
    await page.waitForSelector('text="New Opportunity"')

    await ai(`Enter '12000' in the Amount field.`, { page, test })
    await ai('Enter Test in the opportunity name input', { page, test })
    await ai(`Input '06/30/24' into the Close Date field`, { page, test })
    await ai('Click on the Stage dropdown', { page, test })
    await ai('Click on the Needs Analysis option', { page, test })
    await ai('Click Save', { page, test })

    const result = ai('Assert that the current stage is "Needs Analysis"', { page, test })
    expect(result).toEqual(true)
  })
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import { test, expect } from '@playwright/test'
import { ai } from '@zerostep/playwright'

test.describe('Yahoo Finance', () => {
  test('get the latest stock price', async ({ page }) => {
    await page.goto('https://finance.yahoo.com')

    const price = await ai('Return the current price for the S&P 500. Strip out all commas.', { page, test })
    const formattedPrice = parseFloat(price)

    expect(formattedPrice > 4000).toEqual(true)
  })
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import { test, expect } from '@playwright/test'
import { ai } from '@zerostep/playwright'

test.describe('Wikipedia', () => {
  test('view article history and verify earliest revision', async ({ page }) => {
    await page.goto('https://en.wikipedia.org/wiki/Software_testing')
    await ai(`Click on "View history" link`, { page, test })

    await page.waitForURL('https://en.wikipedia.org/w/index.php?title=Software_testing&action=history')
    await ai('Sort by "oldest"', { page, test })

    await page.waitForURL('https://en.wikipedia.org/w/index.php?title=Software_testing&action=history&dir=prev')
    const date = await ai('What is the date of the first revision listed on this page?', { page, test })

    expect(date).toEqual('16 April 2004')
  })
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import { test, expect } from '@playwright/test'
import { ai } from '@zerostep/playwright'

test.describe('New York Times', () => {
  test('go to section and verify ad is displayed', async ({ page }) => {
    await page.goto('https://www.nytimes.com')

    await ai(`Hover over the World top nav item`, { page, test })
    await ai('Click the "World" section', { page, test })

    await page.waitForURL('https://www.nytimes.com/section/world')
    const cta = await ai('What is the CTA of the ad at the top of the page?', { page, test })

    console.log('Call to action is: ', cta)
  })
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import { test, expect } from '@playwright/test'
import { ai } from '@zerostep/playwright'

test.describe('GitHub', () => {
  test('verify the number of labels in a repo', async ({ page }) => {
    await page.goto('https://github.com/zerostep-ai/zerostep')
    await ai(`Click on the Issues tabs`, { page, test })

    await page.waitForURL('https://github.com/zerostep-ai/zerostep/issues')
    await ai('Click on Labels', { page, test })

    await page.waitForURL('https://github.com/zerostep-ai/zerostep/labels')
    const numLabels = await ai('How many labels are listed?', { page, test })

    expect(parseInt(numLabels)).toEqual(9)
  })
})
View all examples →

Why use ZeroStep?

Use the good parts of Playwright while avoiding common E2E testing pitfalls

The Conventional Approach
  • Selectors are tightly coupled to the application's markup.
  • Every action must be precisely translated to code, making E2E tests much slower to implement than unit and integration tests.
  • Complex scenarios are difficult to automate and constantly break.
  • E2E tests can only be written after the functionality it's testing is feature-complete.
Testing with ZeroStep
  • No selectors are used, ever. ZeroStep's AI assistant determines what actions to take at runtime.
  • Build tests quickly by expressing actions and assertions as plain text instructions.
  • If you can express what you want tested, you can automate it.
  • Since tests aren't coupled to implementation details of the application, you can take a TDD-approach to writing E2E tests.

Pricing

We provide a generous free tier and straight-forward pricing

Free
$0
/ month
500 ai() function calls per month
‐ Unlimited users
Get started
Team
$20
/ month
2,000 ai() function calls per month
‐ Unlimited users
Get started