microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
67.32k stars 3.71k forks source link

[BUG] 2 chrome browsers opened when running a test against selenium 4 grid. #22240

Open quldude opened 1 year ago

quldude commented 1 year ago

System info

Source code

const config: PlaywrightTestConfig = {
  testDir: '.',
  /* Maximum time one test can run for. */
  timeout: 3600 * 1000,
  expect: {
    /**
     * Maximum time expect() should wait for the condition to be met.
     * For example in `await expect(locator).toHaveText();`
     */
    timeout: 5 * 1000,
  },
  /* 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,
  retries: 1,
  /* 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'], ['list', { printSteps: true }]],
  globalSetup: require.resolve('./lib/global-setup'),
  /* 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: process.env.CI ? process.env.TEST_SERVER_URL : 'http://localhost:3000',

    /* Use data-qa as the default test-id attribute */
    testIdAttribute: 'data-qa',

    /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
    headless: false,
    userAgent: `${devices['Desktop Chrome'].userAgent} ${customUserAgentSuffix}`,
    channel: 'chrome',
  },

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

Steps

Expected

Only 1 chrome browser opened with test site page..

Actual

2 chrome browsers opened. One opens with blank page and the other opens with test site page.

pavelfeldman commented 1 year ago

Selenium Grid support in Playwright is highly experimental, not sure what's happening there, will leave open for the others to help if they can.

UkrainianHulk commented 1 year ago

Same here.

annguyen2805 commented 1 year ago

same here. when running playwright with selenium grid 4.10 with playwright appear 2 chrome in Node.

egorsoroka8 commented 4 months ago

Hi everyone, I'm experiencing the same problem with a Linux node. I don't have an in-depth understanding of Selenium Grid processes, but if I get correctly, when we attach to the node, WebDriver automatically opens a browser instance. If we use the built-in Playwright page fixture, it also opens a browser, resulting in two browser instances.

After some experiments, I managed to avoid the second instance from opening and use the first one. You can create a new project, install the 'playwright' and 'webdriverio' packages, and use the following code:

import { chromium } from 'playwright';
import { remote } from 'webdriverio';

const grid = {
  ip: 'my_ip', // your selenium hub ip
  port: 4444, // your selenium hub port
};

(async () => {
  // Connect to Selenium Grid via WebDriver
  const browser = await remote({
    capabilities: {
      browserName: 'chrome',
      platformName: 'linux', // set here desired os
    },
    hostname: grid.ip,
    port: grid.port,
    path: '/wd/hub'
  });

  // Get browser session id
  const sessionId = browser['sessionId'];
  console.log(`sessionId: ${sessionId}`);

  // Get browser end point
  const wsEndPoint = `ws://${grid.ip}:${grid.port}/session/${sessionId}/se/cdp`;
  console.log(`wsEndPoint: ${wsEndPoint}`);

  // Get browser page
  const pwBrowser = await chromium.connectOverCDP(wsEndPoint);
  const context = pwBrowser.contexts()[0];
  const page = context.pages()[0];

  // Run test
  await page.goto('https://google.com');
  await page.waitForTimeout(20_000); // just to have time to check browser in node
  const title = await page.title();

  // Log result
  console.log(title);

  // Close 
  await pwBrowser.close();
  await browser.deleteSession();
})();

There is a possibility that my conclusions are not entirely correct and the situation is a little different, but I think that the truth is somewhere nearby.

@pavelfeldman Since Selenium Grid works in experimental mode, I assume that this case will not be processed on the playwright side, but maybe you can suggest another way to get the browser sessionId without installation WebdriverIO? I can see it in logs when running tests through Selenium Grid.

selenium-playwright-logs

Thanks in advance.