Integrations - shuckster/viddy GitHub Wiki

viddy 🍊 docs

Both the Puppeteer and PlayWright integrations are integrated in the same way, by calling viddyIn and/or viddyWellIn on a page object:

const { viddyIn, viddyWellIn } = require('viddy/playwright')
const { viddyIn, viddyWellIn } = require('viddy/puppeteer')

// ... 

const viddy = await viddyIn(page)
const viddyWell = await viddyWellIn(page)

viddyIn will inject the viddy API into a Puppeteer or PlayWright page. Essentially, it just drops the browser-build of viddy into the page you want and offers some wrappers around page.evaluate() to access the API.

The test suite uses both PlayWright and Puppeteer, so you can take a look there if you want to see some working examples.

Unlike the core viddy API, the integration methods added by viddyIn/viddyWellIn all return Promises, and with the exception of .hasContent() will reject with an error if they fail.

Use viddyWellIn to access the array-returning versions. These do not reject, but instead resolve their Promises to empty arrays when they fail.

🎭 PlayWright example

import { viddyIn /*, viddyWellIn */ } from 'viddy/playwright'

async(() => {
  let browser = await chromium.launch()
  let page = await browser.newPage()
  let viddy = await viddyIn(page)

  await viddy.hasContent('hello')
  // true | false

  await viddy.innerText('hello')
  // "hello, world!"

  const sel = await viddy.for(/click here/i, {
    above: 'title'
  })

  // ^ Unique selector of the first match in the page
  // Since it returns a selector, you can use it with
  // other PlayWright methods like page.click:

  await page.click(sel)

  await viddy
    .waitFor(/click here/i, { below: 'title' })
    .then(sel => page.click(sel))

  // ^ waitFor() returns a selector just like
  // selectorOf() but it'll wait up to 5
  // seconds for the page to contain the query
  // if it doesn't exist

  // Change the timeout like this:
  viddy.waitFor.timesOutAfterMs(1000) // 1 second

  // Or specify an ad-hoc timeout in the Query object:
  await viddy.waitFor(/click here/i, {
    below: 'title',
    timeoutInMs: 1000
  })

  let price = await viddy.matchText(/\d+\.\d+/, {
    near: 'again'
  })

  // ^ If matchText pattern is a RegExp, only the text
  // matching it will be returned. If it's a RegExp
  // with capture-groups, the full result-array
  // will be returned. If the pattern is a string,
  // the full innerText will be returned

  await (await viddy.whenCta('Accept Cookies'))
    .exists(sel => page.click(sel))
    .absent(() => console.log('cookies already accepted'))

  // With our powers combined:
  await viddy
    .for(/click here/i, { below: 'title' })
    .then(sel => page.click(sel))
    .then(() => viddy.waitFor(/\d+\.\d+/, { timeoutInMs: 2000 }))
    .then(sel => viddy.innerText({ selector: sel }))
    .then(console.log)

  await browser.close()
})()

🤡 Puppeteer example

import { viddyIn /*, viddyWellIn */ } from 'viddy/puppeteer'

async(() => {
  let browser = await puppeteer.launch()
  let page = await browser.newPage()
  let viddy = await viddyIn(page)

  await viddy.hasContent('hello')
  // true | false

  await viddy.innerText('hello')
  // "hello, world!"

  const sel = await viddy.for(/click here/i, {
    above: 'title'
  })

  // ^ Unique selector of the first match in the page
  // Since it returns a selector, you can use it with
  // other Puppeteer methods like page.click:

  await page.click(sel)

  await viddy
    .waitFor(/click here/i, { below: 'title' })
    .then(sel => page.click(sel))

  // ^ waitFor() returns a selector just like
  // selectorOf() but it'll wait up to 5
  // seconds for the page to contain the query
  // if it doesn't exist

  // Change the timeout like this:
  viddy.waitFor.timesOutAfterMs(1000) // 1 second

  // Or specify an ad-hoc timeout in the Query object:
  await viddy.waitFor(/click here/i, {
    below: 'title',
    timeoutInMs: 1000
  })

  let price = await viddy.matchText(/\d+\.\d+/, {
    near: 'again'
  })

  // ^ If matchText pattern is a RegExp, only the text
  // matching it will be returned. If it's a RegExp
  // with capture-groups, the full result-array
  // will be returned. If the pattern is a string,
  // the full innerText will be returned

  await (await viddy.whenCta('Accept Cookies'))
    .exists(sel => page.click(sel))
    .absent(() => console.log('cookies already accepted'))

  // With our powers combined:
  await viddy
    .for(/click here/i, { below: 'title' })
    .then(sel => page.click(sel))
    .then(() => viddy.waitFor(/\d+\.\d+/, { timeoutInMs: 2000 }))
    .then(sel => viddy.innerText({ selector: sel }))
    .then(console.log)

  await browser.close()
})()