[BUG] Can't run tests in TeamCity using Firefox and the Playwright Docker image
See original GitHub issueContext:
- Playwright Version: 1.24.2
- Operating System: Linux
- Node.js version: 16.16.0
- Browser: Firefox
- Extra: Tests are run in the Playwright Docker container image
Code Snippet
Help us help you! Put down a short code snippet that illustrates your bug and that we can run and debug locally. For example:
// global-setup.ts
import { chromium, FullConfig } from '@playwright/test';
import { GatewayLogin } from './tests/PageObjectModels/Gateway/login-page';
async function globalSetup(config: FullConfig) {
const { baseURL, storageState, ignoreHTTPSErrors } = config.projects[0].use;
const browser = await chromium.launch();
const context = await browser.newContext({
locale: 'en-us',
ignoreHTTPSErrors,
});
const page = await context.newPage();
try {
await context.tracing.start({ screenshots: true, snapshots: true });
const gatewayLogin = new GatewayLogin(page);
await page.goto(baseURL!);
await gatewayLogin.username.fill(process.env.MARTIN1_USERNAME!);
await gatewayLogin.password.fill(process.env.MARTIN1_PASSWORD!);
await Promise.all([
page.waitForNavigation({url: baseURL! }),
page.locator('text=Sign In').click(),
]);
// Save signed-in state to 'storageState.json'.
await page.context().storageState({ path: storageState as string });
await context.tracing.stop({
path: './test-results/setup-trace.zip',
});
await browser.close();
} catch (error) {
await context.tracing.stop({
path: './test-results/failed-setup-trace.zip',
});
await page.close();
throw error;
}
}
export default globalSetup;
// playwright.config.ts
import type { PlaywrightTestConfig } from '@playwright/test';
import { devices, expect } from '@playwright/test';
import matchers from 'expect-axe-playwright';
import dotenv from 'dotenv';
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
dotenv.config();
/* expect-axe-playwright settings*/
expect.extend(matchers);
/**
* See https://playwright.dev/docs/test-configuration.
*/
const config: PlaywrightTestConfig = {
testDir: './tests',
/* Maximum time one test can run for. */
timeout: 40 * 1000,
expect: {
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 10000,
},
// Tell all tests to load signed-in state from 'storageState.json'.
globalSetup: require.resolve('./global-setup'),
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Stop the test run after reaching this number of failed tests and skip any tests that were not executed yet. This is useful to avoid wasting resources on broken test suites. */
maxFailures: process.env.CI ? 10 : undefined,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: 1,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
//reporter: process.env.CI ? 'dot' : 'list',
reporter: process.env.CI
? [
['list'],
[
'playwright-teamcity-reporter',
{ testMetadataArtifacts: 'test-results', logConfig: false },
],
]
: 'list',
// reporter: [
// ['list'],
// ['playwright-teamcity-reporter', { testMetadataArtifacts: 'test-results' }],
// ],
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* expect-axe-playwright settings*/
axeOptions: {
runOnly: {
type: 'tag',
values: ['wcag2a', 'wcag2aa'],
},
},
ignoreHTTPSErrors: true,
storageState: 'storageState.json',
/* 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.BASE_URL,
/* Collect trace when retrying the failed test. See v */
trace: 'retain-on-failure',
},
/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
testIgnore: Array(
/mobileviewshould.spec.ts/,
/digitalintakeshould.spec.ts/
),
use: {
...devices['Desktop Chrome'],
},
},
{
name: 'firefox',
testIgnore: Array(
/mobileviewshould.spec.ts/,
/digitalintakeshould.spec.ts/
),
use: {
...devices['Desktop Firefox'],
},
},
{
name: 'webkit',
testIgnore: Array(
/mobileviewshould.spec.ts/,
/digitalintakeshould.spec.ts/
),
use: {
...devices['Desktop Safari'],
},
},
/* Test against mobile viewports. */
{
name: 'Mobile Chrome',
testIgnore: Array(
/smoketestshould.spec.ts/,
/epimshould.spec.ts/,
/draftandcollaborationshould.spec.ts/,
/reviewandapprovalshould.spec.ts/
),
use: {
...devices['Pixel 5'],
},
},
{
name: 'iPhone 13 Mobile Safari',
testIgnore: Array(
/smoketestshould.spec.ts/,
/epimshould.spec.ts/,
/draftandcollaborationshould.spec.ts/,
/reviewandapprovalshould.spec.ts/
),
use: {
...devices['iPhone 13'],
},
},
{
name: 'iPhone 13 Pro Max Mobile Safari',
testIgnore: Array(
/smoketestshould.spec.ts/,
/epimshould.spec.ts/,
/draftandcollaborationshould.spec.ts/,
/reviewandapprovalshould.spec.ts/
),
use: {
...devices['iPhone 13 Pro Max'],
},
},
{
name: 'iPhone 12 Mobile Safari',
testIgnore: Array(
/smoketestshould.spec.ts/,
/epimshould.spec.ts/,
/draftandcollaborationshould.spec.ts/,
/reviewandapprovalshould.spec.ts/
),
use: {
...devices['iPhone 12'],
},
},
{
name: 'Samsung Galaxy S22 Ultra 5G Mobile Safari',
testIgnore: Array(
/smoketestshould.spec.ts/,
/epimshould.spec.ts/,
/draftandcollaborationshould.spec.ts/,
/reviewandapprovalshould.spec.ts/
),
use: {
...devices['iPhone 12'],
},
},
/* Test against branded browsers. */
{
name: 'Microsoft Edge',
use: {
channel: 'msedge',
},
},
{
name: 'Google Chrome',
use: {
channel: 'chrome',
},
},
],
/* 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,
// },
};
export default config;
//example.spec.ts
import { test, expect } from '@playwright/test';
test('homepage has Playwright in title and get started link linking to the intro page', async ({ page }) => {
await page.goto('https://playwright.dev/');
// Expect a title "to contain" a substring.
await expect(page).toHaveTitle(/Playwright/);
// create a locator
const getStarted = page.locator('text=Get Started');
// Expect an attribute "to be strictly equal" to the value.
await expect(getStarted).toHaveAttribute('href', '/docs/intro');
// Click the get started link.
await getStarted.click();
// Expects the URL to contain intro.
await expect(page).toHaveURL(/.*intro/);
});
Describe the bug
When I run these tests in TeamCity using Chrome or Safari, it will say it is running the test using one worker and the tests will run. I use the following shell scripts: “npx playwright test tests/smoketestshould --project=chromium” “npx playwright test tests/smoketestshould --project=webkit” When run using Firefox (“npx playwright test tests/smoketestshould --project=firefox”) it will say it is running tests on 1 worker and then hang indefinitely (longest I let it run was 16 hours).
The only way I have found to fix it was to use this shell script: chown root . npx playwright test tests/smoketestshould --project=firefox
This was found while working out another issue. The person assisting said, “It might be due to how Firefox stores its files in the temporary partition, and depending on the docker setup it might work or not.”
Is there any reason the extra line in the shell script is needed when running these tests in the Playwright Docker container image?
Issue Analytics
- State:
- Created a year ago
- Comments:18 (8 by maintainers)
No worries! I’ve been trying to think of how to recreate it locally. It would take spinning up the TeamCity build agent Docker image and then spin up the Playwright Docker image in it on a Linux machine. I am not sure I am going to have the time to set something like that up right now. Considering that the workaround is to add “chown root .” I am going to keep doing that. As I said, this wasn’t necessarily asking something to be fixed, but to investigate why Firefox permissions act differently. Should I ever have the time to set up something to recreate it locally, I can reopen this or create a new issue. Than you again for your time and help!
Thanks @mxschmitt for sending that! I gave that a go. With “chown root .” in the shell script, this was the results:
With that line removed, I got this: