پرش به محتوای اصلی

انتظار

هنگام نوشتن تست‌ها، اغلب نیاز دارید که مقادیر را با شرایط خاصی بررسی کنید. expect به شما امکان دسترسی به تعدادی "matcher" را می‌دهد که به شما امکان می‌دهد چیزهای مختلف را روی browser، یک element یا شیء mock اعتبارسنجی کنید.

گزینه‌های پیش‌فرض

این گزینه‌های پیش‌فرض در زیر به گزینه‌های waitforTimeout و waitforInterval که در تنظیمات قرار داده شده‌اند متصل هستند.

فقط در صورتی که می‌خواهید برای تاییدات خود زمان انتظار خاصی را تنظیم کنید، گزینه‌های زیر را تنظیم کنید.

{
wait: 2000, // ms to wait for expectation to succeed
interval: 100, // interval between attempts
}

اگر می‌خواهید زمان‌های انتظار و فواصل متفاوتی را انتخاب کنید، این گزینه‌ها را به این شکل تنظیم کنید:

// wdio.conf.js
import { setOptions } from 'expect-webdriverio'

export const config = {
// ...
before () {
setOptions({ wait: 5000 })
},
// ...
}

گزینه‌های Matcher

هر matcher می‌تواند چندین گزینه داشته باشد که به شما امکان می‌دهد تایید را تغییر دهید:

گزینه‌های دستور
نامنوعجزئیات
waitnumberزمان به میلی‌ثانیه برای انتظار برای موفقیت انتظار. پیش‌فرض: 3000
intervalnumberفاصله بین تلاش‌ها. پیش‌فرض: 100
beforeAssertionfunctionتابعی که قبل از انجام تایید فراخوانی می‌شود
afterAssertionfunctionتابعی که پس از انجام تایید فراخوانی می‌شود و شامل نتایج تایید است
messagestringپیام کاربر برای اضافه کردن قبل از خطای تایید
گزینه‌های رشته

این گزینه علاوه بر گزینه‌های دستور هنگامی که رشته‌ها تایید می‌شوند می‌تواند استفاده شود.

نامنوعجزئیات
ignoreCasebooleanاعمال toLowerCase به هر دو مقدار واقعی و مورد انتظار
trimbooleanاعمال trim به مقدار واقعی
replaceReplacer | Replacer[]جایگزینی بخش‌هایی از مقدار واقعی که با رشته/RegExp مطابقت می‌کنند. جایگزین می‌تواند یک رشته یا یک تابع باشد.
containingbooleanانتظار می‌رود مقدار واقعی شامل مقدار مورد انتظار باشد، در غیر این صورت برابری دقیق.
asStringbooleanممکن است برای اجبار به تبدیل مقدار خاصیت به رشته مفید باشد
atStartbooleanانتظار می‌رود مقدار واقعی با مقدار مورد انتظار شروع شود
atEndbooleanانتظار می‌رود مقدار واقعی با مقدار مورد انتظار پایان یابد
atIndexnumberانتظار می‌رود مقدار واقعی در شاخص معین دارای مقدار مورد انتظار باشد
گزینه‌های عددی

این گزینه می‌تواند علاوه بر گزینه‌های دستور هنگامی که اعداد تایید می‌شوند اعمال شود.

نامنوعجزئیات
eqnumberبرابر
ltenumberکمتر یا مساوی
gtenumberبزرگتر یا مساوی

مدیریت موجودیت‌های HTML

یک موجودیت HTML یک قطعه متن ("رشته") است که با یک علامت و (&) شروع می‌شود و با نقطه ویرگول (;) پایان می‌یابد. موجودیت‌ها اغلب برای نمایش کاراکترهای رزرو شده (که در غیر این صورت به عنوان کد HTML تفسیر می‌شوند) و کاراکترهای نامرئی (مانند فضاهای بدون شکست، مانند  ) استفاده می‌شوند.

برای یافتن یا تعامل با چنین عنصری از معادل یونیکد موجودیت استفاده کنید. به عنوان مثال:

<div data="Some&nbsp;Value">Some&nbsp;Text</div>
const myElem = await $('div[data="Some\u00a0Value"]')
await expect(myElem).toHaveAttribute('data', 'div[Some\u00a0Value')
await expect(myElem).toHaveText('Some\u00a0Text')

می‌توانید تمام مراجع یونیکد را در مشخصات HTML پیدا کنید.

نکته: یونیکد به حروف بزرگ و کوچک حساس نیست، بنابراین هر دو \u00a0 و \u00A0 کار می‌کنند. برای یافتن عنصر در بازرسی مرورگر، u را از یونیکد حذف کنید، مثلاً: div[data="Some\00a0Value"]

Matchers مرورگر

toHaveUrl

بررسی می‌کند که آیا مرورگر در یک صفحه خاص است.

استفاده
await browser.url('https://webdriver.io/')
await expect(browser).toHaveUrl('https://webdriver.io')
استفاده
await browser.url('https://webdriver.io/')
await expect(browser).toHaveUrl(expect.stringContaining('webdriver'))

toHaveTitle

بررسی می‌کند که آیا وب‌سایت دارای عنوان خاصی است.

استفاده
await browser.url('https://webdriver.io/')
await expect(browser).toHaveTitle('WebdriverIO · Next-gen browser and mobile automation test framework for Node.js')
await expect(browser).toHaveTitle(expect.stringContaining('WebdriverIO'))

toHaveClipboardText

بررسی می‌کند که آیا مرورگر متن خاصی در کلیپ‌بورد خود ذخیره کرده است.

استفاده
import { Key } from 'webdriverio'

await browser.keys([Key.Ctrl, 'a'])
await browser.keys([Key.Ctrl, 'c'])
await expect(browser).toHaveClipboardText('some clipboard text')
await expect(browser).toHaveClipboardText(expect.stringContaining('clipboard text'))

Matchers عنصر

toBeDisplayed

تابع isDisplayed را روی عنصر داده شده فراخوانی می‌کند.

استفاده
const elem = await $('#someElem')
await expect(elem).toBeDisplayed()

toExist

تابع isExisting را روی عنصر داده شده فراخوانی می‌کند.

استفاده
const elem = await $('#someElem')
await expect(elem).toExist()

toBePresent

مشابه با toExist.

استفاده
const elem = await $('#someElem')
await expect(elem).toBePresent()

toBeExisting

مشابه با toExist.

استفاده
const elem = await $('#someElem')
await expect(elem).toBeExisting()

toBeFocused

بررسی می‌کند که آیا عنصر فوکوس دارد. این تایید فقط در بستر وب کار می‌کند.

استفاده
const elem = await $('#someElem')
await expect(elem).toBeFocused()

toHaveAttribute

بررسی می‌کند که آیا یک عنصر دارای یک صفت خاص با مقدار مشخص است.

استفاده
const myInput = await $('input')
await expect(myInput).toHaveAttribute('class', 'form-control')
await expect(myInput).toHaveAttribute('class', expect.stringContaining('control'))

toHaveAttr

مشابه با toHaveAttribute.

استفاده
const myInput = await $('input')
await expect(myInput).toHaveAttr('class', 'form-control')
await expect(myInput).toHaveAttr('class', expect.stringContaining('control'))

toHaveElementClass

بررسی می‌کند که آیا یک عنصر دارای یک نام کلاس واحد است. می‌تواند همچنین با یک آرایه به عنوان پارامتر فراخوانی شود وقتی عنصر می‌تواند چندین نام کلاس داشته باشد.

استفاده
const myInput = await $('input')
await expect(myInput).toHaveElementClass('form-control', { message: 'Not a form control!' })
await expect(myInput).toHaveElementClass(['form-control' , 'w-full'], { message: 'not full width' })
await expect(myInput).toHaveElementClass(expect.stringContaining('form'), { message: 'Not a form control!' })

toHaveElementProperty

بررسی می‌کند که آیا یک عنصر دارای یک خاصیت خاص است.

استفاده
const elem = await $('#elem')
await expect(elem).toHaveElementProperty('height', 23)
await expect(elem).not.toHaveElementProperty('height', 0)

toHaveValue

بررسی می‌کند که آیا یک عنصر ورودی دارای یک مقدار خاص است.

استفاده
const myInput = await $('input')
await expect(myInput).toHaveValue('admin-user', { ignoreCase: true })
await expect(myInput).toHaveValue(expect.stringContaining('user'), { ignoreCase: true })

toBeClickable

با فراخوانی isClickable روی عنصر بررسی می‌کند که آیا یک عنصر قابل کلیک است.

استفاده
const elem = await $('#elem')
await expect(elem).toBeClickable()

toBeDisabled

با فراخوانی isEnabled روی عنصر بررسی می‌کند که آیا یک عنصر غیرفعال است.

استفاده
const elem = await $('#elem')
await expect(elem).toBeDisabled()
// same as
await expect(elem).not.toBeEnabled()

toBeEnabled

با فراخوانی isEnabled روی عنصر بررسی می‌کند که آیا یک عنصر فعال است.

استفاده
const elem = await $('#elem')
await expect(elem).toBeEnabled()
// same as
await expect(elem).not.toBeDisabled()

toBeSelected

با فراخوانی isSelected روی عنصر بررسی می‌کند که آیا یک عنصر انتخاب شده است.

استفاده
const elem = await $('#elem')
await expect(elem).toBeSelected()

toBeChecked

مشابه با toBeSelected.

استفاده
const elem = await $('#elem')
await expect(elem).toBeChecked()

toHaveComputedLabel

بررسی می‌کند که آیا عنصر دارای یک برچسب WAI-ARIA محاسبه شده خاص است. می‌تواند همچنین با یک آرایه به عنوان پارامتر فراخوانی شود در موردی که عنصر می‌تواند برچسب‌های مختلفی داشته باشد.

استفاده
await browser.url('https://webdriver.io/')
const elem = await $('a[href="https://github.com/webdriverio/webdriverio"]')
await expect(elem).toHaveComputedLabel('GitHub repository')
await expect(elem).toHaveComputedLabel(expect.stringContaining('repository'))
استفاده
await browser.url('https://webdriver.io/')
const elem = await $('a[href="https://github.com/webdriverio/webdriverio"]')
await expect(elem).toHaveComputedLabel(['GitHub repository', 'Private repository'])
await expect(elem).toHaveComputedLabel([expect.stringContaining('GitHub'), expect.stringContaining('Private')])

toHaveComputedRole

بررسی می‌کند که آیا عنصر دارای یک نقش WAI-ARIA محاسبه شده خاص است. می‌تواند همچنین با یک آرایه به عنوان پارامتر فراخوانی شود در موردی که عنصر می‌تواند نقش‌های مختلفی داشته باشد.

استفاده
await browser.url('https://webdriver.io/')
const elem = await $('[aria-label="Skip to main content"]')
await expect(elem).toHaveComputedRole('region')
await expect(elem).toHaveComputedRole(expect.stringContaining('ion'))
استفاده
await browser.url('https://webdriver.io/')
const elem = await $('[aria-label="Skip to main content"]')
await expect(elem).toHaveComputedRole(['region', 'section'])
await expect(elem).toHaveComputedRole([expect.stringContaining('reg'), expect.stringContaining('sec')])

toHaveHref

بررسی می‌کند که آیا عنصر لینک دارای یک هدف لینک خاص است.

استفاده
const link = await $('a')
await expect(link).toHaveHref('https://webdriver.io')
await expect(link).toHaveHref(expect.stringContaining('webdriver.io'))

مشابه با toHaveHref.

استفاده
const link = await $('a')
await expect(link).toHaveLink('https://webdriver.io')
await expect(link).toHaveLink(expect.stringContaining('webdriver.io'))

toHaveId

بررسی می‌کند که آیا عنصر دارای یک صفت id خاص است.

استفاده
const elem = await $('#elem')
await expect(elem).toHaveId('elem')

toHaveText

بررسی می‌کند که آیا عنصر دارای یک متن خاص است. می‌تواند همچنین با یک آرایه به عنوان پارامتر فراخوانی شود در موردی که عنصر می‌تواند متن‌های مختلفی داشته باشد.

استفاده
await browser.url('https://webdriver.io/')
const elem = await $('.container')
await expect(elem).toHaveText('Next-gen browser and mobile automation test framework for Node.js')
await expect(elem).toHaveText(expect.stringContaining('test framework for Node.js'))
await expect(elem).toHaveText(['Next-gen browser and mobile automation test framework for Node.js', 'Get Started'])
await expect(elem).toHaveText([expect.stringContaining('test framework for Node.js'), expect.stringContaining('Started')])

در صورتی که لیستی از عناصر در div زیر وجود داشته باشد:

<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>

می‌توانید آنها را با استفاده از یک آرایه تایید کنید:

const elem = await $$('ul > li')
await expect(elem).toHaveText(['Coffee', 'Tea', 'Milk'])

toHaveHTML

بررسی می‌کند که آیا عنصر دارای یک متن خاص است. می‌تواند همچنین با یک آرایه به عنوان پارامتر فراخوانی شود در موردی که عنصر می‌تواند متن‌های مختلفی داشته باشد.

استفاده
await browser.url('https://webdriver.io/')
const elem = await $('.hero__subtitle')
await expect(elem).toHaveHTML('<p class="hero__subtitle">Next-gen browser and mobile automation test framework for Node.js</p>')
await expect(elem).toHaveHTML(expect.stringContaining('Next-gen browser and mobile automation test framework for Node.js'))
await expect(elem).toHaveHTML('Next-gen browser and mobile automation test framework for Node.js', { includeSelectorTag: false })
استفاده
await browser.url('https://webdriver.io/')
const elem = await $('.hero__subtitle')
await expect(elem).toHaveHTML(['Next-gen browser and mobile automation test framework for Node.js', 'Get Started'], { includeSelectorTag: false })
await expect(elem).toHaveHTML([expect.stringContaining('automation test framework for Node.js'), expect.stringContaining('Started')], { includeSelectorTag: false })

toBeDisplayedInViewport

با فراخوانی isDisplayedInViewport روی عنصر بررسی می‌کند که آیا یک عنصر در ناحیه قابل مشاهده است.

استفاده
const elem = await $('#elem')
await expect(elem).toBeDisplayedInViewport()

toHaveChildren

تعداد فرزندان عنصر را با فراخوانی دستور element.$('./*') بررسی می‌کند.

استفاده
const list = await $('ul')
await expect(list).toHaveChildren() // the list has at least one item
// same as
await expect(list).toHaveChildren({ gte: 1 })

await expect(list).toHaveChildren(3) // the list has 3 items
// same as
await expect(list).toHaveChildren({ eq: 3 })

toHaveWidth

بررسی می‌کند که آیا عنصر دارای عرض خاصی است.

استفاده
await browser.url('http://github.com')
const logo = await $('.octicon-mark-github')
await expect(logo).toHaveWidth(32)

toHaveHeight

بررسی می‌کند که آیا عنصر دارای ارتفاع خاصی است.

استفاده
await browser.url('http://github.com')
const logo = await $('.octicon-mark-github')
await expect(logo).toHaveHeight(32)

toHaveSize

بررسی می‌کند که آیا عنصر دارای اندازه خاصی است.

استفاده
await browser.url('http://github.com')
const logo = await $('.octicon-mark-github')
await expect(logo).toHaveSize({ width: 32, height: 32 })

toBeElementsArrayOfSize

تعداد عناصر دریافتی با استفاده از دستور $$ را بررسی می‌کند.

نکته: این matcher آرایه عبور داده شده را با آخرین عناصر به‌روز می‌کند اگر تاییدیه موفق باشد. با این حال، اگر متغیر را مجدداً تخصیص داده‌اید، باید عناصر را دوباره دریافت کنید.

استفاده
const listItems = await $$('ul>li')
await expect(listItems).toBeElementsArrayOfSize(5) // 5 items in the list

await expect(listItems).toBeElementsArrayOfSize({ lte: 10 })
// same as
assert.ok(listItems.length <= 10)

Matchers شبکه

toBeRequested

بررسی می‌کند که mock فراخوانی شده است

استفاده
const mock = browser.mock('**/api/todo*')
await expect(mock).toBeRequested()

toBeRequestedTimes

بررسی می‌کند که mock برای تعداد مورد انتظار فراخوانی شده است

استفاده
const mock = browser.mock('**/api/todo*')
await expect(mock).toBeRequestedTimes(2) // await expect(mock).toBeRequestedTimes({ eq: 2 })

await expect(mock).toBeRequestedTimes({ gte: 5, lte: 10 }) // request called at least 5 times but less than 11

toBeRequestedWith

بررسی می‌کند که mock مطابق با گزینه‌های مورد انتظار فراخوانی شده است.

بیشتر گزینه‌ها از matcher‌های جزئی expect/jasmine مانند expect.objectContaining پشتیبانی می‌کنند

استفاده
const mock = browser.mock('**/api/todo*', { method: 'POST' })

await expect(mock).toBeRequestedWith({
url: 'http://localhost:8080/api/todo', // [optional] string | function | custom matcher
method: 'POST', // [optional] string | array
statusCode: 200, // [optional] number | array
requestHeaders: { Authorization: 'foo' }, // [optional] object | function | custom matcher
responseHeaders: { Authorization: 'bar' }, // [optional] object | function | custom matcher
postData: { title: 'foo', description: 'bar' }, // [optional] object | function | custom matcher
response: { success: true }, // [optional] object | function | custom matcher
})

await expect(mock).toBeRequestedWith({
url: expect.stringMatching(/.*\/api\/.*/i),
method: ['POST', 'PUT'], // either POST or PUT
statusCode: [401, 403], // either 401 or 403
requestHeaders: headers => headers.Authorization.startsWith('Bearer '),
postData: expect.objectContaining({ released: true, title: expect.stringContaining('foobar') }),
response: r => Array.isArray(r) && r.data.items.length === 20
})

Matcher اسنپ‌شات

WebdriverIO از تست‌های اسنپ‌شات پایه و همچنین تست اسنپ‌شات DOM پشتیبانی می‌کند.

toMatchSnapshot

بررسی می‌کند که آیا هر شیء دلخواه با یک مقدار خاص مطابقت دارد. اگر یک WebdriverIO.Element را عبور دهید، به طور خودکار وضعیت outerHTML آن را اسنپ‌شات می‌گیرد.

استفاده
// snapshot arbitrary objects (no "await" needed here)
expect({ foo: 'bar' }).toMatchSnapshot()
// snapshot `outerHTML` of WebdriverIO.Element (DOM snapshot, requires "await")
await expect($('elem')).toMatchSnapshot()
// snapshot result of element command
await expect($('elem').getCSSProperty('background-color')).toMatchSnapshot()

toMatchInlineSnapshot

به طور مشابه، می‌توانید از toMatchInlineSnapshot() برای ذخیره اسنپ‌شات به صورت درون‌خطی در فایل تست استفاده کنید. برای مثال، با:

await expect($('img')).toMatchInlineSnapshot()

به جای ایجاد یک فایل اسنپ‌شات، WebdriverIO مستقیماً فایل تست را برای به‌روزرسانی اسنپ‌شات به عنوان یک رشته تغییر می‌دهد:

await expect($('img')).toMatchInlineSnapshot(`"<img src="/public/apple-touch-icon-precomposed.png">"`)

Matchers اسنپ‌شات تصویری

matcher‌های زیر به عنوان بخشی از افزونه @wdio/visual-service پیاده‌سازی شده‌اند و فقط زمانی که سرویس راه‌اندازی شده باشد در دسترس هستند. مطمئن شوید که دستورالعمل‌های راه‌اندازی را به درستی دنبال می‌کنید.

toMatchElementSnapshot

بررسی می‌کند که آیا عنصر داده شده با اسنپ‌شات خط پایه مطابقت دارد.

استفاده
await expect($('.hero__title-logo')).toMatchElementSnapshot('wdioLogo', 0, {
// options
})

نتیجه مورد انتظار به طور پیش‌فرض 0 است، بنابراین می‌توانید همان تاییدیه را به صورت زیر بنویسید:

await expect($('.hero__title-logo')).toMatchElementSnapshot('wdioLogo', {
// options
})

یا اصلاً هیچ گزینه‌ای ارسال نکنید:

await expect($('.hero__title-logo')).toMatchElementSnapshot()

toMatchScreenSnapshot

بررسی می‌کند که آیا صفحه نمایش فعلی با اسنپ‌شات خط پایه مطابقت دارد.

استفاده
await expect(browser).toMatchScreenSnapshot('partialPage', 0, {
// options
})

نتیجه مورد انتظار به طور پیش‌فرض 0 است، بنابراین می‌توانید همان تاییدیه را به صورت زیر بنویسید:

await expect(browser).toMatchScreenSnapshot('partialPage', {
// options
})

یا اصلاً هیچ گزینه‌ای ارسال نکنید:

await expect(browser).toMatchScreenSnapshot('partialPage')

toMatchFullPageSnapshot

بررسی می‌کند که آیا اسکرین‌شات صفحه کامل با اسنپ‌شات خط پایه مطابقت دارد.

استفاده
await expect(browser).toMatchFullPageSnapshot('fullPage', 0, {
// options
})

نتیجه مورد انتظار به طور پیش‌فرض 0 است، بنابراین می‌توانید همان تاییدیه را به صورت زیر بنویسید:

await expect(browser).toMatchFullPageSnapshot('fullPage', {
// options
})

یا اصلاً هیچ گزینه‌ای ارسال نکنید:

await expect(browser).toMatchFullPageSnapshot('fullPage')

toMatchTabbablePageSnapshot

بررسی می‌کند که آیا اسکرین‌شات صفحه کامل شامل نشانه‌های tab با اسنپ‌شات خط پایه مطابقت دارد.

استفاده
await expect(browser).toMatchTabbablePageSnapshot('tabbable', 0, {
// options
})

نتیجه مورد انتظار به طور پیش‌فرض 0 است، بنابراین می‌توانید همان تاییدیه را به صورت زیر بنویسید:

await expect(browser).toMatchTabbablePageSnapshot('tabbable', {
// options
})

یا اصلاً هیچ گزینه‌ای ارسال نکنید:

await expect(browser).toMatchTabbablePageSnapshot('tabbable')

استفاده از عبارات منظم

همچنین می‌توانید مستقیماً از عبارات منظم برای تمام matcher‌هایی که مقایسه متنی انجام می‌دهند استفاده کنید.

استفاده
await browser.url('https://webdriver.io/')
const elem = await $('.container')
await expect(elem).toHaveText(/node\.js/i)
await expect(elem).toHaveText([/node\.js/i, 'Get Started'])
await expect(browser).toHaveTitle(/webdriverio/i)
await expect(browser).toHaveUrl(/webdriver\.io/)
await expect(elem).toHaveElementClass(/Container/i)

Matchers پیش‌فرض

علاوه بر matcher‌های expect-webdriverio، می‌توانید از تاییدیه‌های داخلی Jest's expect یا expect/expectAsync برای Jasmine استفاده کنید.

Asymmetric Matchers

WebdriverIO از استفاده از matcher‌های نامتقارن در هر جایی که مقادیر متنی را مقایسه می‌کنید پشتیبانی می‌کند، به عنوان مثال:

await expect(browser).toHaveTitle(expect.stringContaining('some title'))

یا

await expect(browser).toHaveTitle(expect.not.stringContaining('some title'))

TypeScript

اگر از WDIO Testrunner استفاده می‌کنید، همه چیز به طور خودکار تنظیم خواهد شد. فقط راهنمای راه‌اندازی را از مستندات دنبال کنید. با این حال، اگر WebdriverIO را با یک testrunner دیگر یا در یک اسکریپت ساده Node.js اجرا می‌کنید، باید expect-webdriverio را به types در tsconfig.json اضافه کنید.

  • "expect-webdriverio" برای همه به‌جز کاربران Jasmine/Jest.
  • "expect-webdriverio/jasmine" برای Jasmine
  • "expect-webdriverio/jest" برای Jest

JavaScript (VSCode)

برای کار کردن تکمیل خودکار در vanilla js، لازم است که jsconfig.json را در ریشه پروژه ایجاد کنید و به تعریف‌های نوع اشاره کنید.

{
"include": [
"**/*.js",
"**/*.json",
"node_modules/expect-webdriverio"
]
}

افزودن matcher‌های خودتان

مشابه با نحوه گسترش expect-webdriverio matcher‌های Jasmine/Jest، افزودن matcher‌های سفارشی نیز امکان‌پذیر است.

  • برای Jasmine به مستندات custom matchers مراجعه کنید
  • برای بقیه به expect.extend Jest مراجعه کنید

matcher‌های سفارشی باید در فایل before wdio اضافه شوند

// wdio.conf.js
{
async before () {
const { addCustomMatchers } = await import('./myMatchers')
addCustomMatchers()
}
}
// myMatchers.js - Jest example
export function addCustomMatchers () {
if (global.expect.expect !== undefined) { // Temporary workaround. See https://github.com/webdriverio/expect-webdriverio/issues/835
global.expect = global.expect.expect;
}

expect.extend({
myMatcher (actual, expected) {
return { pass: actual === expected, message: () => 'some message' }
}
})
}

Welcome! How can I help?

WebdriverIO AI Copilot