Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd08f9dc

Browse files
committed
feat: Add TypeScript test support with tsx loader (v4.0.0-beta.19)
- Implemented Option 1A: tsx/cjs loader for TypeScript test files in ESM- Added comprehensive TypeScript test support documentation- Created lib/utils/loaderCheck.js utility for TypeScript setup validation- Updated init command to include tsx and configure require: ['tsx/cjs']- Added tsx as devDependency and optional peerDependency- Improved requireModules() to resolve packages from user's directory- Added helpful error messages when TypeScript tests found without loader- Created comprehensive test suite demonstrating TS features (enums, interfaces, imports)- All unit tests passing (488 passing)- TypeScript tests verified working with tsx/cjs loaderKey Changes:* docs/typescript.md: New section on TypeScript tests in ESM with tsx/cjs* docs/configuration.md: Updated require section with ESM examples* lib/codecept.js: Added TypeScript validation and improved module resolution* lib/command/init.js: Auto-configure tsx/cjs for TypeScript projects* lib/utils/loaderCheck.js: NEW - TypeScript loader validation utility* package.json: Bumped version to 4.0.0-beta.19, added tsx* test/data/typescript-static-imports/: Complete TypeScript test examplesTechnical Details:- Uses tsx/cjs (CommonJS hooks) instead of tsx/esm (ESM loaders)- Works because Mocha internally uses require() for test loading- tsx/cjs intercepts require() calls and transpiles .ts files on-the-fly- Supports all TypeScript features: enums, interfaces, types, decorators- Zero configuration required (no tsconfig.json needed)- Fast transpilation using esbuild
1 parent4ff9a23 commitd08f9dc

File tree

14 files changed

+1323
-23
lines changed

14 files changed

+1323
-23
lines changed

‎TYPESCRIPT_ESM_ARCHITECTURE.md‎

Lines changed: 793 additions & 0 deletions
Large diffs are not rendered by default.

‎docs/configuration.md‎

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,40 +33,78 @@ After running `codeceptjs init` it should be saved in test root.
3333

3434
##Require
3535

36-
Requires described module before run. This option is useful for assertion libraries, so you may`--require should` instead of manually invoking`require('should')` within each test file. It can be used with relative paths, e.g.`"require": ["/lib/somemodule"]`, and installed packages.
36+
Requires modules before running tests. This is useful for:
37+
-**Assertion libraries:** e.g.,`'should'` instead of manually requiring it in each test
38+
-**TypeScript loaders:** Enable TypeScript test files in ESM or CommonJS projects
39+
-**Setup modules:** Initialize testing environment
40+
-**Custom modules:** With relative paths like`"require": ["./lib/setup"]`
3741

38-
You can register ts-node, so you can use Typescript in tests with ts-node package
42+
###TypeScript Support
3943

40-
```js
41-
exports.config= {
42-
tests:'./*_test.js',
43-
timeout:10000,
44-
output:'',
44+
####For ESM Projects (CodeceptJS 4.x)
45+
46+
Use modern loaders that support ES Modules:
47+
48+
**Using tsx (recommended - fast, zero config):**
49+
50+
```typescript
51+
// codecept.conf.ts
52+
exportconst config= {
53+
tests:'./**/*_test.ts',
54+
require: ['tsx/cjs'],// ← Modern TypeScript loader
4555
helpers: {},
4656
include: {},
47-
bootstrap:false,
48-
mocha: {},
49-
// require modules
50-
require: ['ts-node/register','should'],
5157
}
5258
```
5359

54-
For array of test pattern
60+
**Using ts-node/esm:**
5561

56-
```js
62+
```typescript
63+
// codecept.conf.ts
64+
exportconst config= {
65+
tests:'./**/*_test.ts',
66+
require: ['ts-node/esm'],// ← Established TypeScript loader
67+
helpers: {},
68+
include: {},
69+
}
70+
```
71+
72+
>**Note:** For ts-node/esm, you need a tsconfig.json with ESM configuration. See[TypeScript documentation](/typescript) for details.
73+
74+
####For CommonJS Projects (CodeceptJS 3.x)
75+
76+
Use the CommonJS loader:
77+
78+
```javascript
79+
// codecept.conf.js
5780
exports.config= {
58-
tests: ['./*_test.js','./sampleTest.js'],
59-
timeout:10000,
60-
output:'',
81+
tests:'./*_test.ts',
82+
require: ['ts-node/register'],// ← CommonJS TypeScript loader
6183
helpers: {},
6284
include: {},
63-
bootstrap:false,
64-
mocha: {},
65-
// require modules
66-
require: ['ts-node/register','should'],
6785
}
6886
```
6987

88+
###Multiple Requires
89+
90+
You can combine multiple modules:
91+
92+
```typescript
93+
// codecept.conf.ts
94+
exportconst config= {
95+
tests: ['./**/*_test.ts','./smoke_test.ts'],
96+
require: [
97+
'tsx/cjs',// TypeScript loader
98+
'should',// Assertion library
99+
'./lib/testSetup'// Custom setup
100+
],
101+
helpers: {},
102+
include: {},
103+
}
104+
```
105+
106+
Modules are loaded in the order specified, before any tests run.
107+
70108
##Dynamic Configuration
71109

72110
By default`codecept.json` is used for configuration. You can override its values in runtime by using`--override` or`-o` option in command line, passing valid JSON as a value:

‎docs/typescript.md‎

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,176 @@ Then a config file and new tests will be created in TypeScript format.
4343

4444
If a config file is set in TypeScript format (`codecept.conf.ts`) package`ts-node` will be used to run tests.
4545

46+
##TypeScript Tests in ESM (CodeceptJS 4.x) <Badgetext="Since 4.0.0"type="tip"/>
47+
48+
CodeceptJS 4.x uses ES Modules (ESM) which requires a different approach for TypeScript test files. While TypeScript**config files** (`codecept.conf.ts`) are automatically transpiled, TypeScript**test files** need a loader.
49+
50+
###Using tsx (Recommended)
51+
52+
[tsx](https://tsx.is) is a modern, fast TypeScript loader built on esbuild. It's the recommended way to run TypeScript tests in CodeceptJS 4.x.
53+
54+
**Installation:**
55+
```bash
56+
npm install --save-dev tsx
57+
```
58+
59+
**Configuration:**
60+
```typescript
61+
// codecept.conf.ts
62+
exportconst config= {
63+
tests:'./**/*_test.ts',
64+
require: ['tsx/cjs'],// ← Enable TypeScript loader for test files
65+
helpers: {
66+
Playwright: {
67+
url:'http://localhost',
68+
browser:'chromium'
69+
}
70+
}
71+
}
72+
```
73+
74+
That's it! Now you can write tests in TypeScript with full language support:
75+
76+
```typescript
77+
// login_test.ts
78+
Feature('Login')
79+
80+
Scenario('successful login', ({I })=> {
81+
I.amOnPage('/login')
82+
I.fillField('email','user@example.com')
83+
I.fillField('password','password123')
84+
I.click('Login')
85+
I.see('Welcome')
86+
})
87+
```
88+
89+
**Why tsx?**
90+
-**Fast:** Built on esbuild, much faster than ts-node
91+
- 🎯**Zero config:** Works without tsconfig.json
92+
- 🚀**Works with Mocha:** Uses CommonJS hooks that Mocha understands
93+
-**Complete:** Handles all TypeScript features (enums, decorators, etc.)
94+
95+
###Using ts-node/esm (Alternative)
96+
97+
If you prefer ts-node:
98+
99+
**Installation:**
100+
```bash
101+
npm install --save-dev ts-node
102+
```
103+
104+
**Configuration:**
105+
```typescript
106+
// codecept.conf.ts
107+
exportconst config= {
108+
tests:'./**/*_test.ts',
109+
require: ['ts-node/esm'],// ← Use ts-node ESM loader
110+
helpers: {/* ...*/ }
111+
}
112+
```
113+
114+
**Required tsconfig.json:**
115+
```json
116+
{
117+
"compilerOptions": {
118+
"module":"ESNext",
119+
"target":"ES2022",
120+
"moduleResolution":"node",
121+
"esModuleInterop":true
122+
},
123+
"ts-node": {
124+
"esm":true,
125+
"experimentalSpecifierResolution":"node"
126+
}
127+
}
128+
```
129+
130+
###Full TypeScript Features in Tests
131+
132+
With tsx or ts-node/esm, you can use complete TypeScript syntax including imports, enums, interfaces, and types:
133+
134+
```typescript
135+
// types.ts
136+
exportenumEnvironment {
137+
TEST='test',
138+
STAGING='staging',
139+
PRODUCTION='production'
140+
}
141+
142+
exportinterfaceUser {
143+
email:string
144+
password:string
145+
}
146+
147+
// login_test.ts
148+
import {Environment,User }from'./types'
149+
150+
const testUser:User= {
151+
email:'test@example.com',
152+
password:'password123'
153+
}
154+
155+
Feature('Login')
156+
157+
Scenario(`Login on ${Environment.TEST}`, ({I })=> {
158+
I.amOnPage('/login')
159+
I.fillField('email',testUser.email)
160+
I.fillField('password',testUser.password)
161+
I.click('Login')
162+
I.see('Welcome')
163+
})
164+
```
165+
166+
###Troubleshooting TypeScript Tests
167+
168+
**Error: "Cannot find module" or "Unexpected token"**
169+
170+
This means the TypeScript loader isn't configured. Make sure:
171+
1. You have`tsx` or`ts-node` installed:`npm install --save-dev tsx`
172+
2. Your config includes the loader in`require` array:`require: ['tsx/cjs']`
173+
3. The loader is specified before test files are loaded
174+
175+
**Error: Module not found when importing from`.ts` files**
176+
177+
Make sure you're using a proper TypeScript loader (`tsx/cjs` or`ts-node/esm`).
178+
179+
**TypeScript config files vs test files**
180+
181+
Note the difference:
182+
-**Config files** (`codecept.conf.ts`, helpers): Automatically transpiled by CodeceptJS
183+
-**Test files** (`*_test.ts`): Need a loader specified in`config.require`
184+
185+
###Migration from CodeceptJS 3.x
186+
187+
If you're upgrading from CodeceptJS 3.x (CommonJS) to 4.x (ESM):
188+
189+
**Old setup (3.x):**
190+
```javascript
191+
// codecept.conf.js
192+
module.exports= {
193+
tests:'./*_test.ts',
194+
require: ['ts-node/register'],// CommonJS loader
195+
helpers: {}
196+
}
197+
```
198+
199+
**New setup (4.x):**
200+
```typescript
201+
// codecept.conf.ts
202+
exportconst config= {
203+
tests:'./*_test.ts',
204+
require: ['tsx/cjs'],// TypeScript loader
205+
helpers: {}
206+
}
207+
```
208+
209+
**Migration steps:**
210+
1. Install tsx:`npm install --save-dev tsx`
211+
2. Update package.json:`"type": "module"`
212+
3. Rename config to`codecept.conf.ts` and use`export const config = {}`
213+
4. Change`require: ['ts-node/register']` to`require: ['tsx/cjs']`
214+
5. Run tests:`npx codeceptjs run`
215+
46216
##Promise-Based Typings
47217

48218
By default, CodeceptJS tests are written in synchronous mode. This is a regular CodeceptJS test:

‎lib/codecept.js‎

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import { globSync } from 'glob'
33
importshufflefrom'lodash.shuffle'
44
importfsPathfrom'path'
55
import{resolve}from'path'
6-
import{fileURLToPath}from'url'
6+
import{fileURLToPath,pathToFileURL}from'url'
77
import{dirname}from'path'
8+
import{createRequire}from'module'
89

910
const__filename=fileURLToPath(import.meta.url)
1011
const__dirname=dirname(__filename)
@@ -18,6 +19,7 @@ import ActorFactory from './actor.js'
1819
importoutputfrom'./output.js'
1920
import{emptyFolder}from'./utils.js'
2021
import{initCodeceptGlobals}from'./globals.js'
22+
import{validateTypeScriptSetup}from'./utils/loaderCheck.js'
2123
importrecorderfrom'./recorder.js'
2224

2325
importstoreListenerfrom'./listener/store.js'
@@ -66,6 +68,21 @@ class Codecept {
6668
modulePath=`${modulePath}.js`
6769
}
6870
}
71+
}else{
72+
// For npm packages, resolve from the user's directory
73+
// This ensures packages like tsx are found in user's node_modules
74+
constuserDir=global.codecept_dir||process.cwd()
75+
76+
try{
77+
// Use createRequire to resolve from user's directory
78+
constuserRequire=createRequire(pathToFileURL(resolve(userDir,'package.json')).href)
79+
constresolvedPath=userRequire.resolve(requiredModule)
80+
modulePath=pathToFileURL(resolvedPath).href
81+
}catch(resolveError){
82+
// If resolution fails, try direct import (will check from CodeceptJS node_modules)
83+
// This is the fallback for globally installed packages
84+
modulePath=requiredModule
85+
}
6986
}
7087
// Use dynamic import for ESM
7188
awaitimport(modulePath)
@@ -246,6 +263,13 @@ class Codecept {
246263
asyncrun(test){
247264
awaitcontainer.started()
248265

266+
// Check TypeScript loader configuration before running tests
267+
consttsValidation=validateTypeScriptSetup(this.testFiles,this.requiringModules||[])
268+
if(tsValidation.hasError){
269+
output.error(tsValidation.message)
270+
process.exit(1)
271+
}
272+
249273
// Ensure translations are loaded for Gherkin features
250274
try{
251275
const{ loadTranslations}=awaitimport('./mocha/gherkin.js')

‎lib/command/init.js‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ export default async function (initPath) {
161161
isTypeScript=true
162162
extension=isTypeScript===true ?'ts' :'js'
163163
packages.push('typescript')
164-
packages.push('ts-node')
164+
packages.push('tsx')// Add tsx for TypeScript support
165165
packages.push('@types/node')
166166
}
167167

@@ -172,6 +172,7 @@ export default async function (initPath) {
172172
config.tests=result.tests
173173
if(isTypeScript){
174174
config.tests=`${config.tests.replace(/\.js$/,`.${extension}`)}`
175+
config.require=['tsx/cjs']// Add tsx/cjs loader for TypeScript tests
175176
}
176177

177178
// create a directory tests if it is included in tests path

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp