Resource library

QA How-To

TestCafe vs Playwright (2026)

TestCafe vs Playwright in 2026: compare browser coverage, waiting, API tests, debugging, and CI with runnable examples to choose the right web testing tool.

17 min read | 3,001 words

TL;DR

For a new JavaScript web test suite, Playwright is usually the stronger default because of browser projects, locators, and traces. TestCafe remains a sound choice when an existing suite delivers reliable coverage and its browser modes fit your requirements. The same local app and tests below make the trade-off concrete.

Key Takeaways

  • Start a new cross-engine suite with Playwright when trace-based debugging and browser projects matter.
  • Keep a productive TestCafe suite unless a measured gap justifies migration.
  • TestCafe uses fixture and test-controller actions; Playwright Test uses fixtures, locators, and web-first assertions.
  • Both tools can test the local UI, issue direct API requests, and inspect browser network traffic.
  • Run TestCafe browsers separately when comparing native automation behavior across engines.
  • Judge tools with representative CI failures and diagnosis time, not a tiny speed benchmark.

TestCafe vs Playwright is a choice between two capable JavaScript web testing tools with different strengths. Choose Playwright for a new suite that needs first-class browser projects, trace-based debugging, and broad control over pages and network traffic. Keep or choose TestCafe when its fixture and test-controller model fits your team, its existing suite is productive, or you need its browser coverage and workflow without a migration. Run the same small app through both before deciding; a tool's syntax matters less than how reliably your team can diagnose a failed build.

This guide builds one local quote page, tests its visible result and API with each runner, then compares browser execution and failure evidence. The example avoids a public demo site so a third-party outage cannot decide your evaluation. Commands assume a Unix-like shell; adapt directory creation and background processes for your platform. The source links near the end point to the official documentation for behavior that can change.

TL;DR

Decision point TestCafe Playwright Test
Main test shape fixture, test, t actions, and Selector test, fixtures such as page and request, locator actions, and expect
Browser setup Uses locally available browsers by alias; check with --list-browsers Installs supported browser binaries with playwright install; configure browser projects
Waiting model Test actions and smart assertions wait for actionable elements or expected values Locators auto-wait for actions; web-first assertions retry expected states
Cross-browser runs Browser aliases on the CLI; mixed engines can change TestCafe's native automation mode Chromium, Firefox, and WebKit projects in one config
Network and API RequestLogger, RequestMock, and t.request page.waitForResponse, routing, and request fixture
Failure inspection Console details, screenshots, and optional video HTML report, traces, screenshots, and optional video
Parallel execution Browser concurrency setting Worker processes and project matrix

For a greenfield suite, start with Playwright unless a concrete TestCafe capability or team constraint changes the decision. Do not rewrite a stable TestCafe suite simply because another runner has more features. Measure the migration against your actual failure rate, browser matrix, and maintenance time.

What You Will Build

  • A tiny HTTP server with one accessible form and a deterministic JSON endpoint.
  • One end-to-end UI check in TestCafe and the same check in Playwright.
  • One direct API check and one browser-network check per tool.
  • A small browser matrix and a repeatable way to inspect failures.

Enter a name, click "Get quote," and expect "Quote ready for Ada." The fetch request lets you distinguish DOM and network assertions. The server stores no shared state, so parallel tests cannot corrupt a record.

Prerequisites

Install a currently supported Node.js release and npm, plus a local Chrome installation for the TestCafe command below. Playwright will download its own browser binaries. If you are on Linux, follow Playwright's documented system dependency instructions when browser installation reports missing libraries. Keep package versions unpinned here; your lockfile records the versions you install and your CI should install from that lockfile.

node --version
npm --version
mkdir testcafe-playwright-lab
cd testcafe-playwright-lab
npm init -y
npm pkg set type=module
npm pkg set scripts.start="node server.mjs"
npm install --save-dev testcafe @playwright/test
npx playwright install chromium firefox webkit
npx testcafe --list-browsers
npx playwright --version

Verify that the last two commands print a browser list containing Chrome and a Playwright version. If Chrome is absent, install it or substitute an available TestCafe browser alias throughout the TestCafe commands. npx playwright install fetches binaries that match the installed Playwright package; avoid copying a browser cache from a different package version. The TestCafe installation guide and Playwright installation guide describe platform details.

Step 1: Create One Deterministic App

Save this as server.mjs in the new lab directory. It uses Node's built-in HTTP server, so there is no app framework to configure. The form's visible labels let the Playwright example use user-facing locators; the stable IDs keep the TestCafe example compact. The JSON endpoint returns the same message that the page eventually displays.

import { createServer } from 'node:http';

const html = `<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><title>Quote lab</title></head>
<body>
  <h1>Quote lab</h1>
  <form id="quote-form">
    <label for="name">Name</label>
    <input id="name" name="name" required>
    <button type="submit">Get quote</button>
  </form>
  <p role="status">Ready</p>
  <script>
    document.querySelector('#quote-form').addEventListener('submit', async event => {
      event.preventDefault();
      const name = document.querySelector('#name').value;
      const response = await fetch('/api/quote?name=' + encodeURIComponent(name));
      const result = await response.json();
      document.querySelector('[role="status"]').textContent = result.message;
    });
  </script>
</body>
</html>`;

createServer((request, response) => {
  const url = new URL(request.url ?? '/', 'http://127.0.0.1:4173');
  if (url.pathname === '/api/quote') {
    const name = (url.searchParams.get('name') ?? '').trim();
    response.writeHead(name ? 200 : 400, { 'content-type': 'application/json' });
    response.end(JSON.stringify({ message: name ? `Quote ready for ${name}` : 'Name required' }));
    return;
  }
  if (url.pathname === '/') {
    response.writeHead(200, { 'content-type': 'text/html; charset=utf-8' });
    response.end(html);
    return;
  }
  response.writeHead(404);
  response.end('Not found');
}).listen(4173, '127.0.0.1', () => console.log('Quote lab on http://127.0.0.1:4173'));

Verify the app before adding a runner. Open the page in a browser, then request the endpoint from a second terminal. Leave npm start running for TestCafe; Playwright's config in Step 3 starts or reuses the same server. A 200 response containing Ada's message proves that the API and port are available. If port 4173 is already in use, change it in the server and every URL below, including Playwright's webServer setting.

npm start
# In a second terminal, from the same directory:
curl 'http://127.0.0.1:4173/api/quote?name=Ada'

Step 2: Write the TestCafe UI Check

Create tests/testcafe/quote.js. The fixture sets the starting page once. t.typeText and t.click express actions, while the Selector reads the status element. TestCafe's assertion checks the final text, rather than merely proving that a button could be clicked. Using a Selector expression inside t.expect also lets TestCafe apply its smart assertion behavior as the fetch completes.

import { Selector } from 'testcafe';

fixture`Quote lab`.page('http://127.0.0.1:4173/');

test('shows the quote after submitting a name', async t => {
  await t
    .typeText('#name', 'Ada')
    .click('button[type="submit"]')
    .expect(Selector('[role="status"]').innerText)
    .eql('Quote ready for Ada');
});

With npm start still running in the other terminal, verify this file with npx testcafe 'chrome:headless' tests/testcafe/quote.js. Expect one passing test. The :headless browser alias changes the display mode, not the application assertion. If your machine has Firefox but no Chrome, use firefox:headless and confirm its alias first with --list-browsers. For a locator-heavy suite, compare the documented TestCafe Selector API against Playwright's locator guidance, especially how each expresses a user's label or role.

npx testcafe 'chrome:headless' tests/testcafe/quote.js

TestCafe's t object groups actions and assertions. Selectors such as #name rely on a DOM contract; a markup refactor can require a test update even when the form looks identical.

Step 3: Write the Playwright UI Check

Create playwright.config.js and tests/playwright/quote.spec.js. The config names three browser projects, gives the test a base URL, and starts the local server when needed. reuseExistingServer lets the server you started for TestCafe remain in place during local runs. On CI, the config requires its own server so a stray process cannot hide a setup error. trace: 'retain-on-failure' keeps a trace for failures without saving a trace from every passing test.

// playwright.config.js
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests/playwright',
  reporter: 'html',
  use: {
    baseURL: 'http://127.0.0.1:4173',
    trace: 'retain-on-failure'
  },
  projects: [
    { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
    { name: 'firefox', use: { ...devices['Desktop Firefox'] } },
    { name: 'webkit', use: { ...devices['Desktop Safari'] } }
  ],
  webServer: {
    command: 'npm start',
    url: 'http://127.0.0.1:4173/',
    reuseExistingServer: !process.env.CI
  }
});
// tests/playwright/quote.spec.js
import { test, expect } from '@playwright/test';

test('shows the quote after submitting a name', async ({ page }) => {
  await page.goto('/');
  await page.getByRole('textbox', { name: 'Name' }).fill('Ada');
  await page.getByRole('button', { name: 'Get quote' }).click();
  await expect(page.getByRole('status')).toHaveText('Quote ready for Ada');
});

Verify with npx playwright test --project=chromium. Expect one passing test. The getByRole calls describe the accessible interface, so they also reveal when a label or button name changes. The final toHaveText is a web-first assertion: it retries while the browser waits for the fetch result. Do not replace it with a fixed sleep. To inspect all projects later, run the suite without --project. For a deeper treatment of role locators, see the Playwright getByRole guide.

npx playwright test --project=chromium

Step 4: Compare Direct API Checks

A UI check can pass even when a server endpoint returns the wrong status for a different input. Add a direct API test to each existing file. TestCafe provides t.request; Playwright Test supplies a request fixture. Both checks use the same absolute URL, validate the HTTP status, and inspect parsed JSON. They test the endpoint without relying on the page's form or JavaScript.

Append this block to tests/testcafe/quote.js. It uses the t already supplied by TestCafe, so no new import is needed. The response's body is parsed as JSON because the local server sets content-type: application/json.

test('returns a quote from the API', async t => {
  const response = await t.request('http://127.0.0.1:4173/api/quote?name=Ada');
  await t.expect(response.status).eql(200);
  await t.expect(response.body.message).eql('Quote ready for Ada');
});

Append the next block to tests/playwright/quote.spec.js. It reuses the file's existing test and expect imports. request.get uses the configured base URL for its relative path. The explicit response.ok() assertion catches a non-2xx response before comparing JSON.

test('returns a quote from the API', async ({ request }) => {
  const response = await request.get('/api/quote?name=Ada');
  expect(response.ok()).toBeTruthy();
  expect(await response.json()).toEqual({ message: 'Quote ready for Ada' });
});

Verify both files. TestCafe should report two passes in Chrome, and Playwright should report two passes in its Chromium project. If the API test succeeds while the UI test fails, investigate the browser-side fetch or DOM update instead of treating the endpoint as broken. If both fail, start with server availability and the exact URL. The TestCafe API testing guide and Playwright API request guide cover larger setup and cleanup patterns.

npx testcafe 'chrome:headless' tests/testcafe/quote.js
npx playwright test --project=chromium tests/playwright/quote.spec.js

Step 5: Observe the Browser Request

Direct requests cannot prove that clicking the button sent the intended URL. Test the browser network path separately. Create tests/testcafe/network.js with a RequestLogger bound to the quote endpoint. TestCafe's smart assertion waits for a matching logged response. The existing local app and server are enough; no network mocking is needed.

// tests/testcafe/network.js
import { RequestLogger } from 'testcafe';

const quoteRequests = RequestLogger(/\/api\/quote\?name=Ada/);

fixture`Quote network`.page('http://127.0.0.1:4173/');

test.requestHooks(quoteRequests)('submitting calls the quote API', async t => {
  await t.typeText('#name', 'Ada').click('button[type="submit"]');
  await t.expect(quoteRequests.contains(record =>
    record.response.statusCode === 200
  )).ok();
});

Create tests/playwright/network.spec.js for the equivalent browser request. Register page.waitForResponse before the click, then await it after the click. Registering later would create a race: a fast local response could arrive before the listener exists. The Playwright predicate checks both the endpoint URL and the status.

// tests/playwright/network.spec.js
import { test, expect } from '@playwright/test';

test('submitting calls the quote API', async ({ page }) => {
  await page.goto('/');
  await page.getByRole('textbox', { name: 'Name' }).fill('Ada');
  const responsePromise = page.waitForResponse(response =>
    response.url().includes('/api/quote?name=Ada') && response.status() === 200
  );
  await page.getByRole('button', { name: 'Get quote' }).click();
  const response = await responsePromise;
  expect((await response.json()).message).toBe('Quote ready for Ada');
});

Verify the new pair directly. Each should report one pass. A request logger and a response waiter answer a different question from the UI assertion: did the browser call the intended endpoint, and what came back? Use such checks where the request is part of the contract, not on every UI test. For failures caused by stubs, compare Playwright network mocking with TestCafe's request hook guide.

npx testcafe 'chrome:headless' tests/testcafe/network.js
npx playwright test --project=chromium tests/playwright/network.spec.js

Step 6: Run a Browser Matrix Without Misreading It

Run TestCafe against Chrome and Firefox in separate commands, then run all three configured Playwright projects. TestCafe can accept multiple browser aliases in one run, but its documentation says a string mixing Chromium and non-Chromium browsers disables native automation. Separate commands keep that mode difference visible while you compare results. Playwright's projects run the same specs in Chromium, Firefox, and WebKit. WebKit is a useful engine check, though it is not identical to testing the installed Safari application.

npx testcafe 'chrome:headless' tests/testcafe
npx testcafe 'firefox:headless' tests/testcafe
npx playwright test

Verify that TestCafe reports three tests for each browser and Playwright reports nine tests across three projects. The count follows from the files above: UI, direct API, and browser network. If one browser is unavailable locally, skip only that TestCafe command and record the missing coverage. A passing Chromium project does not stand in for Firefox or WebKit. The Playwright projects guide explains how to add devices or environments without copying test files; TestCafe's browser guide explains aliases and native mode changes.

Do not infer a performance winner from these runs. Startup, worker count, machine load, and artifact settings affect elapsed time. Compare representative suites on the same CI workers and include failure diagnosis time.

Step 7: Capture Useful Failure Evidence

First, keep the passing baseline. Then make one intentional local failure by changing the expected message in a copy of a test, or by stopping the server before a run. Restore the test afterward. TestCafe can save screenshots on assertion failures. Playwright's configured retain-on-failure trace gives you a timeline with DOM snapshots and network activity, and its HTML report links to retained artifacts. Choose the evidence that answers your team's usual question: wrong locator, wrong response, timing, or browser-specific rendering.

npx testcafe 'chrome:headless' tests/testcafe -s path=artifacts/testcafe,takeOnFails=true
npx playwright test --project=chromium --trace on
npx playwright show-report

Verify a deliberate TestCafe failure creates an image under artifacts/testcafe; a passing run may create no failure screenshot. With --trace on, Playwright records traces even for passing tests so you can inspect the report immediately. The report server is interactive and keeps running until you stop it. For CI, avoid forcing traces for every pass: retain-on-failure in the config keeps the more relevant records. See the Playwright trace-on-retry guide and the official TestCafe screenshot guide.

TestCafe offers screenshots and optional video. Playwright's trace shows the page before and after an action alongside network activity. Both still need explicit business assertions.

TestCafe vs Playwright: Weigh the Architecture

TestCafe's fixture model makes browser choice primarily a runner concern. That can help when the same suite already runs on team-managed browsers or when a TestCafe migration would disrupt many stable tests. Its Selector, t.expect, roles, request hooks, and API request capability cover far more than basic click scripts. It also supports remote and cloud browsers through documented modes, but the native automation FAQ lists constraints for remote browsers and multiple windows. Check the specific mode you plan to use before promising parity across your fleet.

Playwright Test treats browser and device combinations as named projects. Its fixtures isolate each test's browser context, while page, request, locators, routing, and traces are part of one runner workflow. That makes it attractive when you need reproducible Chromium, Firefox, and WebKit coverage, popup handling, rich network control, or a report that lets another engineer replay the steps of a failure. The cost is a larger configuration surface: workers, retries, projects, browser downloads, and artifacts must be managed deliberately.

Waiting is a common source of mistaken comparisons. TestCafe's smart assertions and Playwright's web-first assertions both retry expected UI states; neither should require routine sleep calls for this example. The APIs still differ. Playwright locators resolve at action time and combine naturally with accessible roles. TestCafe selectors evaluate page elements through its test-controller flow. When a test is flaky, inspect the state transition and assertion first, then decide whether the runner's waiting behavior is involved. For a broader framework baseline, read the end-to-end testing guide.

Which Should You Choose in TestCafe vs Playwright?

Choose Playwright for a new JavaScript or TypeScript suite when your priorities include cross-engine projects, network control, popup workflows, and trace-centered debugging. The tutorial's three-project run shows how one config can apply the same specs to several browser engines. If your team already uses Playwright for API setup or component checks, sharing its request fixture and assertion style can reduce tool switching. Start with a small smoke path like this lab, then add only the browsers and retries that provide decision-making value.

Choose TestCafe when you have meaningful coverage in it and the current suite meets its release gate. A rewrite spends engineering time and can lose assertions, data setup, or browser cases that are not obvious from the file count. It may also be a natural fit if your organization relies on its fixture, role, or browser-provider workflow. Investigate native automation restrictions for your specific browsers rather than assuming every TestCafe feature behaves the same in every mode.

For a migration decision, collect a sample of real failures from the past month. Reimplement two or three representative tests, including a difficult one with authentication or network interception. Compare review time, CI failures, diagnosis time, and browser coverage. Keep application state and worker resources equivalent. If Playwright solves a measured bottleneck, migrate by feature area and maintain one source of truth for each flow. If not, invest in better selectors and test isolation in the existing suite. The Playwright test runner tutorial is a starting point for a pilot.

Troubleshooting

TestCafe says it cannot find Chrome -> Run npx testcafe --list-browsers, install Chrome, or use a listed alias. Playwright's downloaded Chromium binary does not automatically mean TestCafe's chrome alias can find a local Chrome installation.

The app URL refuses connections -> Start npm start for TestCafe and check curl 'http://127.0.0.1:4173/api/quote?name=Ada'. For Playwright, inspect the webServer error and confirm the port and URL match server.mjs.

The UI result stays at Ready -> Confirm the page script ran and the /api/quote response was 200. The browser-network tests isolate request failures; the direct API tests isolate server failures.

Only one browser fails -> Read that project's artifact and check browser-specific behavior before increasing timeouts. TestCafe's mixed-engine mode may also switch its automation method, so reproduce with a single browser alias.

A network assertion misses the response -> Register Playwright's response waiter before the click. In TestCafe, attach RequestLogger to the test before the page action. A listener added after the request cannot recover past traffic.

CI cannot launch a Playwright browser -> Run the browser installation step in CI and install the system libraries specified by Playwright for that runner image. Keep the package and browser binaries matched; do not invent or hard-code an image tag from memory.

Interview Questions and Answers

The structured questions below cover the architecture choices an interviewer is likely to probe. Explain the trade-off with a concrete example from a suite you have run, then describe how you would prove the choice in CI. For more practice, use the TestCafe interview questions and Playwright interview questions.

Common Mistakes

  • Migrating by file count alone. Compare assertions, fixtures, browser coverage, and failure diagnostics; equal numbers of files do not imply equal risk coverage.
  • Using a fixed wait after a click. Assert the visible result with TestCafe's smart assertion or Playwright's web-first assertion. The wait should follow the behavior being tested.
  • Treating direct API success as UI success. A working endpoint does not prove the form submits, the browser receives the response, or the status text updates.
  • Claiming WebKit is installed Safari. Playwright's WebKit project checks the engine it ships. Add a real Safari check if your release contract requires that application.
  • Mixing TestCafe browser engines without noticing mode changes. The runner documents that mixed Chromium and non-Chromium aliases affect native automation. Reproduce failures in the exact mode used by CI.
  • Comparing raw speed without a controlled workload. Browser cache, workers, retries, app setup, and report collection change the result. Include diagnosis time in the comparison.
  • Turning on expensive artifacts for every CI pass. Keep detailed evidence for failures and sample deliberately when investigating intermittent behavior.

Where To Go Next

Expand the lab into a realistic login or checkout flow only after these six core browser runs pass. Add a failure injection, such as returning a 500 for one name, and require both suites to explain it clearly. Then follow the Playwright API request examples, Playwright locator guide, or TestCafe tutorial according to the tool you selected. If you are preparing for an automation role, record the trade-off you measured and rehearse it in interview practice.

Official references: TestCafe browser support, TestCafe native automation FAQ, Playwright locators, Playwright web server configuration, and Playwright Trace Viewer. Check these pages when upgrading dependencies because browser behavior and runner options can change.

Conclusion

TestCafe vs Playwright has no universal migration answer. Playwright is the stronger default for a new, cross-engine suite with trace-driven debugging; TestCafe can remain the right production choice when an existing suite is stable and its browser mode supports your workflows. Run the local example, replace its quote action with one real release-critical flow, and choose from the failure evidence your team can actually use.

Interview Questions and Answers

How would you choose between TestCafe and Playwright for a new suite?

I would list required browsers, authentication flows, network controls, CI constraints, and failure artifacts first. Then I would implement the same critical path in both and compare maintenance and failure diagnosis. Playwright is my default for cross-engine projects and traces, but an existing TestCafe platform can outweigh that default.

What is the difference between a TestCafe Selector and a Playwright locator?

Both identify elements for actions and assertions, but their test styles differ. TestCafe uses `Selector` within its test-controller API, while Playwright locators are built from `page` and can use roles, labels, text, or test IDs. I would prefer a user-facing locator when it represents the product contract and a stable test ID when text is intentionally variable.

How do the tools wait for an asynchronous UI result?

In TestCafe, I pass the selector property into `t.expect` so its smart assertion can retry. In Playwright, I use a web-first assertion such as `await expect(page.getByRole('status')).toHaveText(...)`. I avoid a fixed sleep because it either wastes time or still fails under load.

How would you prove that a button sent the correct HTTP request?

A direct API test proves the endpoint, not the button. In TestCafe I attach a `RequestLogger` before the action and assert a matching response. In Playwright I create `page.waitForResponse` before clicking, then assert the returned status and body.

What does a Playwright project add to a browser matrix?

A project names a browser or configuration and runs the same specs under that setting. It lets the report show Chromium, Firefox, and WebKit results separately without copying test files. I still check whether the selected engine matches the exact browser product my release needs.

Why can a mixed-browser TestCafe run behave differently?

TestCafe's documentation says a browser string combining Chromium and non-Chromium browsers disables native automation for that run. This can change capabilities and failure characteristics compared with a Chrome-only run. I reproduce an issue in the same browser and mode used by CI before changing the test.

What evidence would you keep from a failed browser test?

I want the assertion, browser and environment, relevant network response, and a view of the UI at failure time. TestCafe can provide console details and failure screenshots; Playwright can retain a trace and expose it through the HTML report. The artifact should help explain cause, not merely prove that a test failed.

How would you migrate a large TestCafe suite safely?

I would inventory release-critical flows and their assertions, then migrate a representative area while both suites run. Each new test must prove the same behavior, including setup and browser coverage. I would remove duplicate coverage only after the Playwright run is stable and CI owners can diagnose failures.

Frequently Asked Questions

Is Playwright better than TestCafe for a new automation project?

Playwright is usually the better starting point when you need Chromium, Firefox, and WebKit projects, trace inspection, and broad network controls. TestCafe may fit better if your team already depends on its fixtures, roles, or browser workflow. Prove the choice with a release-critical flow in both tools.

Does TestCafe require Selenium or WebDriver?

No. TestCafe has its own automation system and uses native browser automation for supported Chromium runs. Its behavior can differ by browser and mode, so check the native automation documentation for the browsers you will run.

Can TestCafe test APIs without a browser UI action?

Yes. `t.request` sends an HTTP request and returns status, headers, and body for assertions. Keep direct API checks separate from browser-network checks when you need to prove that a click caused the request.

Can Playwright replace TestCafe tests without rewriting them?

No automatic one-to-one conversion should be assumed. Map each TestCafe fixture, selector, role, hook, and assertion to the behavior it proves, then implement and verify that behavior in Playwright. Migrate a small representative feature area first.

Which tool handles cross-browser tests more clearly?

Playwright's named projects put Chromium, Firefox, and WebKit in one configuration and report each project separately. TestCafe selects installed browsers through aliases on the CLI. Its automation mode can change when a run mixes Chromium and non-Chromium aliases.

Do either TestCafe or Playwright need hard-coded sleeps?

Routine UI checks should use their waiting assertions instead. TestCafe's smart assertions and Playwright's web-first assertions retry the expected state. If a test still fails, inspect the actual page transition and network response before adding a delay.

Is Playwright WebKit the same as testing Safari?

A WebKit project tests Playwright's bundled WebKit browser engine. It is useful cross-engine coverage, but it is not a run in the installed Safari application. Add a separate Safari check if that exact application is in your support contract.

Related Guides