vitest-dev/vitest · error · Error

Method "frameLocator" is not supported by the

Error message

Method "frameLocator" is not supported by the "${provider}" provider.

What it means

page.frameLocator targets nested iframe contexts and requires a full browser provider that understands frame switching. The default page stub throws with the active provider name; preview mode runs inside a single iframe and has no frame-navigation capability, so the call cannot be satisfied.

Solutions

  1. Configure test.browser.provider to 'playwright' or 'webdriverio' to get frameLocator support.
  2. Under preview, access the iframe's document directly via document.querySelector('iframe').contentDocument (same-origin only).
  3. Restructure tests to avoid cross-frame interactions under preview.

Example fix

// before
const frame = page.frameLocator('iframe#child')
// after (preview provider, same-origin)
const doc = document.querySelector('iframe#child')!.contentDocument!
const btn = doc.querySelector('button')!
Defensive patterns

Strategy: validation

Validate before calling

if (getBrowserState().provider === 'preview') {
  // same-origin iframe access via contentDocument
  document.querySelector('iframe')?.contentDocument?.querySelector('button')
} else {
  page.frameLocator('iframe').getByRole('button')
}

Type guard

function supportsFrames(): boolean {
  return ['playwright', 'webdriverio'].includes(getBrowserState().provider ?? '')
}

Prevention

When it happens

Trigger: Calling page.frameLocator('iframe#child') while provider is 'preview'; testing embedded video/ad iframes without a full provider; copying Playwright frame examples into a preview-provider project.

Common situations: Tests for embedded widgets/portals; default provider config; missing provider install.

Related errors


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/ad3838006860c315. Report an issue: GitHub.

Appendix: source

Thrown at packages/browser/src/client/tester/context.ts:464

    throw new Error(`Method "getByTestId" is not supported by the "${provider}" provider.`)
  },
  getByAltText() {
    throw new Error(`Method "getByAltText" is not supported by the "${provider}" provider.`)
  },
  getByPlaceholder() {
    throw new Error(`Method "getByPlaceholder" is not supported by the "${provider}" provider.`)
  },
  getByText() {
    throw new Error(`Method "getByText" is not supported by the "${provider}" provider.`)
  },
  getByTitle() {
    throw new Error(`Method "getByTitle" is not supported by the "${provider}" provider.`)
  },
  elementLocator() {
    throw new Error(`Method "elementLocator" is not supported by the "${provider}" provider.`)
  },
  frameLocator() {
    throw new Error(`Method "frameLocator" is not supported by the "${provider}" provider.`)
  },
  extend(methods) {
    for (const key in methods) {
      (page as any)[key] = (methods as any)[key].bind(page)
    }
    return page
  },
}

function convertToLocator(element: Element | Locator): Locator {
  if (element instanceof Element) {
    return page.elementLocator(element)
  }
  return element
}

function getTaskFullName(task: RunnerTask): string {
  return task.suite ? `${getTaskFullName(task.suite)} ${task.name}` : task.name

View on GitHub (pinned to 1fa9837ec2)