<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: v1.32.3</li>
<li>Operating System: 22.04.2 LTS (Jammy Jellyfish)</li>
<li>Browser: WebKit</li>
<li>Node.js Version: v18.15.0</li>
</ul>
<h3 dir="auto">Source code</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I provided exact source code that allows reproducing the issue locally.</li>
</ul>




<p dir="auto"><strong>app.js</strong></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="const playwright = require('playwright');

async function captureScreenshot() {
    const options = {
        headless: true,
        viewport: { width: 1920, height: 1080 }
    }
    const browser = await playwright.webkit.launch(options);
    const context = await browser.newContext();
    const page = await context.newPage();
    
    await page.goto('https://fonts.google.com/specimen/Montserrat');
    await page.waitForLoadState('networkidle');
    await page.screenshot({path: `ss-headless-webkit-montserrat.png`, fullPage: true});
    await browser.close();
}

captureScreenshot();"><pre class="notranslate"><span class="pl-k">const</span> <span class="pl-s1">playwright</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'playwright'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">async</span> <span class="pl-k">function</span> <span class="pl-en">captureScreenshot</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">const</span> <span class="pl-s1">options</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
        <span class="pl-c1">headless</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span>
        <span class="pl-c1">viewport</span>: <span class="pl-kos">{</span> <span class="pl-c1">width</span>: <span class="pl-c1">1920</span><span class="pl-kos">,</span> <span class="pl-c1">height</span>: <span class="pl-c1">1080</span> <span class="pl-kos">}</span>
    <span class="pl-kos">}</span>
    <span class="pl-k">const</span> <span class="pl-s1">browser</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">playwright</span><span class="pl-kos">.</span><span class="pl-c1">webkit</span><span class="pl-kos">.</span><span class="pl-en">launch</span><span class="pl-kos">(</span><span class="pl-s1">options</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">const</span> <span class="pl-s1">context</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">browser</span><span class="pl-kos">.</span><span class="pl-en">newContext</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">const</span> <span class="pl-s1">page</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">context</span><span class="pl-kos">.</span><span class="pl-en">newPage</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    
    <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">goto</span><span class="pl-kos">(</span><span class="pl-s">'https://fonts.google.com/specimen/Montserrat'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">waitForLoadState</span><span class="pl-kos">(</span><span class="pl-s">'networkidle'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">screenshot</span><span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-c1">path</span>: <span class="pl-s">`ss-headless-webkit-montserrat.png`</span><span class="pl-kos">,</span> <span class="pl-c1">fullPage</span>: <span class="pl-c1">true</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-s1">browser</span><span class="pl-kos">.</span><span class="pl-en">close</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-en">captureScreenshot</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Steps</strong></p>
<ul dir="auto">
<li>node app.js</li>
</ul>
<p dir="auto"><strong>Expected</strong><br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/121084902/232419487-546f733f-7da8-492d-a330-a0653a35cb07.png"><img src="https://user-images.githubusercontent.com/121084902/232419487-546f733f-7da8-492d-a330-a0653a35cb07.png" alt="image" style="max-width: 100%;"></a></p>
<p dir="auto"><strong>Actual</strong><br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/121084902/232419755-cd73eca8-4358-4f54-86af-799121842dd4.png"><img src="https://user-images.githubusercontent.com/121084902/232419755-cd73eca8-4358-4f54-86af-799121842dd4.png" alt="image" style="max-width: 100%;"></a></p>
<h3 dir="auto">Context</h3>
<p dir="auto">My use case is to capture screenshots on different browsers.</p>
<p dir="auto">It works perfectly fine on my local setup (details given below) for all the browsers i.e <code class="notranslate">chromium</code>, <code class="notranslate">firefox</code> and <code class="notranslate">webkit</code>. But it doesn't work on <code class="notranslate">Ubuntu</code> specifically for <code class="notranslate">webkit</code>, works fine for <code class="notranslate">chromium</code> and <code class="notranslate">firefox</code>. (Ubuntu runs on the Docker image <code class="notranslate">mcr.microsoft.com/playwright:v1.32.3-jammy</code>. However, I also tried it on a live machine, it produces the same screenshots as the container)</p>
<p dir="auto">The issue seems to be font rendering. <code class="notranslate">Webkit</code> on <code class="notranslate">Ubuntu</code> can't render different weights of the font</p>
<p dir="auto">macOS (Local setup)</p>
<ul dir="auto">
<li>Playwright Version: v1.32.3</li>
<li>Operating System: Ventura Version 13.3.1</li>
<li>Browser: WebKit</li>
<li>Node.js Version: v18.15.0</li>
</ul>
<h3 dir="auto">Similar Issues</h3>
<p dir="auto"><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1324714630" data-permission-text="Title is private" data-url="https://github.com/microsoft/playwright/issues/16104" data-hovercard-type="issue" data-hovercard-url="/microsoft/playwright/issues/16104/hovercard" href="https://github.com/microsoft/playwright/issues/16104">#16104</a>,  <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="935521290" data-permission-text="Title is private" data-url="https://github.com/microsoft/playwright/issues/7441" data-hovercard-type="issue" data-hovercard-url="/microsoft/playwright/issues/7441/hovercard" href="https://github.com/microsoft/playwright/issues/7441">#7441</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="641388729" data-permission-text="Title is private" data-url="https://github.com/microsoft/playwright/issues/2626" data-hovercard-type="issue" data-hovercard-url="/microsoft/playwright/issues/2626/hovercard" href="https://github.com/microsoft/playwright/issues/2626">#2626</a></p>
<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: [v1.32.2]</li>
<li>Operating System: [macOS BigSur]</li>
<li>Browser: [Chrome 112.0.5615.121]</li>
<li>Other info:</li>
</ul>
<h3 dir="auto">Source code</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I provided exact source code that allows reproducing the issue locally.</li>
</ul>




<p dir="auto"><strong>Link to the GitHub repository with the repro</strong></p>
<p dir="auto"><strong>Config file</strong></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="export default defineConfig({
  testDir: './tests',
  /* Maximum time one test can run for. */
  timeout: 600 * 1000,
  globalTimeout: 1000 * 60 * 30,
  expect: {
    /**
     * Maximum time expect() should wait for the condition to be met.
     * For example in `await expect(locator).toHaveText();`
     */
    timeout: 10000,
  },
  /* Run tests in files in parallel */
  fullyParallel: true,
  /* Fail the build on CI if you accidentally left test.only in the source code. */
  forbidOnly: !!process.env.CI,
  /* Retry on CI only */
  retries: process.env.CI ? 2 : 0,
  /* Opt out of parallel tests on CI. */
  workers: process.env.CI ? 1 : undefined,
  /* Reporter to use. See https://playwright.dev/docs/test-reporters */
  reporter: [['html', { open: 'always', port: process.env.NODE_SERVICE_PORT || '9103', host: 'local.webullbroker.com' }]],
  /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
  use: {
    /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
    actionTimeout: 0,
    /* Base URL to use in actions like `await page.goto('/')`. */
    // baseURL: 'http://localhost:3000',

    /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
    trace: 'on-first-retry',
  },

  /* Configure projects for major browsers */
  projects: [
    { name: 'setup', testMatch: /.*\.setup\.ts/ },
    {
      name: 'chromium',
      testMatch: 'List.spec.ts',
      use: {
        ...devices['Desktop Chrome'],
        storageState: 'playwright/.auth/user.json',
      },
      dependencies: ['setup'],
    },
  ],

  /* Folder for test artifacts such as screenshots, videos, traces, etc. */
  // outputDir: 'test-results/',

  /* Run your local dev server before starting the tests */
  // webServer: {
  //   command: 'npm run start',
  //   port: 3000,
  // },
})"><pre class="notranslate"><code class="notranslate">export default defineConfig({
  testDir: './tests',
  /* Maximum time one test can run for. */
  timeout: 600 * 1000,
  globalTimeout: 1000 * 60 * 30,
  expect: {
    /**
     * Maximum time expect() should wait for the condition to be met.
     * For example in `await expect(locator).toHaveText();`
     */
    timeout: 10000,
  },
  /* Run tests in files in parallel */
  fullyParallel: true,
  /* Fail the build on CI if you accidentally left test.only in the source code. */
  forbidOnly: !!process.env.CI,
  /* Retry on CI only */
  retries: process.env.CI ? 2 : 0,
  /* Opt out of parallel tests on CI. */
  workers: process.env.CI ? 1 : undefined,
  /* Reporter to use. See https://playwright.dev/docs/test-reporters */
  reporter: [['html', { open: 'always', port: process.env.NODE_SERVICE_PORT || '9103', host: 'local.webullbroker.com' }]],
  /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
  use: {
    /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
    actionTimeout: 0,
    /* Base URL to use in actions like `await page.goto('/')`. */
    // baseURL: 'http://localhost:3000',

    /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
    trace: 'on-first-retry',
  },

  /* Configure projects for major browsers */
  projects: [
    { name: 'setup', testMatch: /.*\.setup\.ts/ },
    {
      name: 'chromium',
      testMatch: 'List.spec.ts',
      use: {
        ...devices['Desktop Chrome'],
        storageState: 'playwright/.auth/user.json',
      },
      dependencies: ['setup'],
    },
  ],

  /* Folder for test artifacts such as screenshots, videos, traces, etc. */
  // outputDir: 'test-results/',

  /* Run your local dev server before starting the tests */
  // webServer: {
  //   command: 'npm run start',
  //   port: 3000,
  // },
})
</code></pre></div>
<p dir="auto"><strong>Steps</strong></p>
<ul dir="auto">
<li>[Run the test]</li>
<li>[Click Traces Image]</li>
</ul>
<p dir="auto"><strong>Expected</strong></p>
<p dir="auto">[html reporter success open]</p>
<p dir="auto"><strong>Actual</strong><br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/25821307/233818469-627e9f45-c4a4-4179-b985-613fde5cfafa.png"><img src="https://user-images.githubusercontent.com/25821307/233818469-627e9f45-c4a4-4179-b985-613fde5cfafa.png" alt="image" style="max-width: 100%;"></a><br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/25821307/233818482-480db917-ed5b-4600-9316-6f47e89cb23a.png"><img src="https://user-images.githubusercontent.com/25821307/233818482-480db917-ed5b-4600-9316-6f47e89cb23a.png" alt="image" style="max-width: 100%;"></a><br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/25821307/233818489-65433d32-7bc4-4643-8e74-be5e81b3c1d2.png"><img src="https://user-images.githubusercontent.com/25821307/233818489-65433d32-7bc4-4643-8e74-be5e81b3c1d2.png" alt="image" style="max-width: 100%;"></a></p>
<p dir="auto">It cannot be accessed by domain name or reverse proxy, but it can be accessed by localhost or 127.0.0.1<br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/25821307/233818566-943496e7-799b-4543-abc5-b4519391209b.png"><img src="https://user-images.githubusercontent.com/25821307/233818566-943496e7-799b-4543-abc5-b4519391209b.png" alt="image" style="max-width: 100%;"></a></p>
<p dir="auto">Error：</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="caught (in promise) TypeError: Cannot read properties of undefined (reading 'register')
    at index.a18c30b0.js:1:3355
    at index.a18c30b0.js:1:3586
(anonymous) @ index.a18c30b0.js:1
(anonymous) @ index.a18c30b0.js:1"><pre class="notranslate"><code class="notranslate">caught (in promise) TypeError: Cannot read properties of undefined (reading 'register')
    at index.a18c30b0.js:1:3355
    at index.a18c30b0.js:1:3586
(anonymous) @ index.a18c30b0.js:1
(anonymous) @ index.a18c30b0.js:1
</code></pre></div>