Skip to content

4.x: Internal API over "import" works from helpers only, it doesn't work from tests/page objects #5635

@mirao

Description

@mirao

Found after the migration of my production project to 4.x. Note it works well in 3.x.
You can reproduce it with the simple quickstart project.

Expected result:

Actual result:

  • Internal API over "import" works only from helpers. See the output below.

Workaround for tests/page objects:

  • Use (globalThis as any).codeceptjs, e.g.
  console.log((globalThis as any).codeceptjs.config.get().helpers.Playwright.browser);

output:

mirao@rog:~/workspace/my$ codeceptjs run --verbose
***************************************
nodeInfo:  24.15.0
osInfo:  Linux 6.17 Ubuntu 24.04.4 LTS 24.04.4 LTS (Noble Numbat)
cpuInfo:  (16) x64 AMD Ryzen 7 9700X 8-Core Processor
chromeInfo:  149.0.7827.114
edgeInfo:  "N/A"
firefoxInfo:  151.0.3
safariInfo:  N/A
playwrightBrowsers:  "chromium: 148.0.7778.96, firefox: 150.0.2, webkit: 26.4"
If you need more detailed info, just run this: npx codeceptjs info
***************************************
CodeceptJS v4.0.7 #StandWithUkraine
Using test root "/home/mirao/workspace/my"
Helpers: Playwright, Custom
Plugins: screenshot, retryFailedStep

My --
/home/mirao/workspace/my/tests/My_test.ts
    [1]  Starting recording promises
    Timeouts: 
 › [Session] Starting singleton browser session
  test something
 › [New Session] {"ignoreHTTPSErrors":false,"acceptDownloads":true}
From helper: chromium
  Scenario()
    [1] Error | TypeError: Cannot read properties of undefined (reading 'Playwright') undefined...
    [1] <teardown>  Stopping recording promises
 › <screenshot> Saving screenshot test_something.failed.png
 › [Screenshot] output/test_something.failed.png
  ✖ FAILED in 237ms

    [2]  Starting recording promises

-- FAILURES:

  1) My
       test something:
     
  Cannot read properties of undefined (reading 'Playwright')
  TypeError: 
      at Test.<anonymous> (tests/My_test.ts:6:42)
      at recorder (node_modules/codeceptjs/lib/mocha/asyncWrapper.js:274:1)
  
  
  ◯ File: file:///home/mirao/workspace/my/tests/My_test.ts
  
  ◯ Artifacts:
  - screenshot: /home/mirao/workspace/my/output/test_something.failed.png
  
  ◯ Metadata:
  - browser: chromium
  - browserVersion: 148.0.7778.96
  - windowSize: 1280x720


  FAIL  | 0 passed, 1 failed   // 435ms

My_test.ts:

import { config } from "codeceptjs";

Feature("My");

Scenario("test something", ({ I }) => {
  console.log("From test:", config.get().helpers.Playwright.browser);
});

custom_helper.ts:

import Helper from '@codeceptjs/helper';
import { config } from "codeceptjs";

class Custom extends Helper {

  // before/after hooks
  /**
   * @protected
   */
  _before() {
    console.log("From helper:", config.get().helpers.Playwright.browser);
  }

  /**
   * @protected
   */
  _after() {
    // remove if not used
  }

  // add custom methods here
  // If you need to access other helpers
  // use: this.helpers['helperName']

}

export default Custom;

codecept.conf.ts

import { setHeadlessWhen, setCommonPlugins } from "@codeceptjs/configure";
// turn on headless mode when running with HEADLESS=true environment variable
// export HEADLESS=true && npx codeceptjs run
setHeadlessWhen(process.env.HEADLESS);

// enable all common plugins https://github.com/codeceptjs/configure#setcommonplugins
setCommonPlugins();

export const config: CodeceptJS.MainConfig = {
  tests: "./tests/*_test.ts",
  output: "./output",
  helpers: {
    Playwright: {
      browser: "chromium",
      url: "http://localhost",
      show: true,
    },
    Custom: {
      require: "./custom_helper.ts",
    },
  },
  include: {
    I: "./steps_file.ts",
  },
  noGlobals: true,
  plugins: {},
  name: "my",
  require: ["tsx/cjs"],
};

tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["ES2022", "DOM"],
    "esModuleInterop": true,
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strictNullChecks": false,
    "types": ["codeceptjs", "node"],
    "declaration": true,
    "skipLibCheck": true
  },
  "exclude": ["node_modules"]
}

package.json

{
  "devDependencies": {
    "@types/node": "^25.9.3",
    "codeceptjs": "^4.0.7",
    "playwright": "^1.60.0",
    "tsx": "^4.22.4",
    "typescript": "^6.0.3"
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions