[Question] Unable to add parameters to Test Options and Playwright Config - Error Fixture "page" has unknown parameter
System info
- Playwright Version: [v1.34.0]
- Operating System: [ macOS 13.3.1]
- Browser: [All, Chromium, Firefox, WebKit]
- Other info: Editor - VSCode
System info
I have no idea where I am going wrong here. The code was working fine until I added a parameter userName: string in TestOptions and add it in config > projects[]
VSCode does say there's an error in my-test.ts but when I switch to the tab, I don't see the error anymore.
https://github.com/microsoft/playwright/assets/122398930/58580a66-80ea-4ecc-9235-171083865d07
Earlier, before upgrading to PW v1.34.0, I wasn't even able to see the error in the spec. The run button for test test("test 1", async ({ page, person, baseURL, userName }) => { just disappeared.
Error in my-test.ts
Fixture "page" has unknown parameter "userName".
Error in spec
Test has unknown parameter "userName".
Source code
Link to the GitHub repository with the repro [https://github.com/siddharth2023/playwrightProjects]
or
Config file
// playwright.config.ts
import { defineConfig, devices } from "@playwright/test";
import type { TestOptions } from "./tests/my-test";
export default defineConfig<TestOptions>({
testDir: "./tests",
/* 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",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
trace: "on-first-retry",
headless: false,
},
/* Configure projects for major browsers */
projects: [
{
name: "duckduck",
use: {
...devices["Desktop Chrome"],
person: "https://duck.com",
baseURL: "https://spreadprivacy.com/",
userName: 'a',
},
},
{
name: "wiki",
use: {
...devices["Desktop Chrome"],
person: "https://wikipedia.org",
baseURL: "https://en.wikipedia.org/wiki/Main_Page",
userName: 'a',
},
},
],
});
// my-test.ts
import { test as base } from "@playwright/test";
export type TestOptions = {
person: string;
baseURL: string;
userName: string;
};
export const test = base.extend<TestOptions>({
// Define an option and provide a default value.
// We can later override it in the config.
person: ["https://github.com", { option: true }],
// Override default "page" fixture.
page: async ({ page, baseURL, person, userName }, use) => {
// await page.pause();
// baseURL = process.env.CI
// ? ${process.env.BASE_URL}
// : "https://playwright.dev/";
await page.goto(baseURL);
console.log(userName);
console.log(person);
// Each test will get a "page" that already has the person name.
await use(page);
},
});
Test file (self-contained)
import { expect } from "@playwright/test";
import { test } from "./my-test";
test("test 1", async ({ page, person, baseURL, userName }) => {
await page.pause();
if(baseURL.includes('wiki')) {
await page.getByPlaceholder('Search Wikipedia').click();
}
});
Steps
- Just load this repo in VSCode and you will see the error
Fixture "page" has unknown parameter "userName"inmy-test.ts
Expected
I should be able to add more parameters and then use them in specs
Actual
VSCode is shows that an unknown parameter exists but I have added it in TestOptions.
Did you already add userName fixture (value, not only the type)? Did you try to start your tests anyway?
Yeah. The value is coming from the config (below). Is that what you meant? Cause that's where I am adding values to both the other params as well.
use: { ...devices["Desktop Chrome"], person: "https://wikipedia.org", baseURL: "https://en.wikipedia.org/wiki/Main_Page", userName: 'a', },
I just added the fixture my-test.ts in my question above.
person: ["https://github.com", { option: true }]
Just do the same for userName.
Ah. That works!!! Thought I could override from config directly. Thanks a ton!
Might need one final advice from you. I am also trying to load extension when the browser loads. Here's my fixture.
import { test as base, chromium, type BrowserContext } from "@playwright/test";
export type TestOptions = {
url:string;
qaEnv: string
};
export const test = base.extend<{
context: BrowserContext;
extensionId: string;
},TestOptions>({
// Define an option and provide a default value.
// We can later override it in the config.
url: ["https://wikipedia.com/", { option: true }],
qaEnv: ["QA", { option: true }],
// Override default "page" fixture.
page: async ({ page, url }, use) => {
console.log(url);
// await page.goto(url);
// Each test will get a "page" that already has the person name.
await use(page);
},
});
I get this error Property 'scope' is missing in type '{ option: true; }' but required in type '{ scope: "worker"; auto?: boolean | undefined; option?: boolean | undefined; timeout?: number | undefined; }'.
How do I handle this?
@siddharth2023 You declared url and qaEnv as worker-scoped options by passing TestOptions as a second template argument. Most likely you need this (note & instead of ,):
export const test = base.extend<{
context: BrowserContext;
extensionId: string;
} & TestOptions>({
// ...
});
@dogzman. That helped. Thank you :)