create-please-test
v2.0.7
Published
Scaffold a new automation test project using please-test
Maintainers
Readme
create-please-test
Scaffold a Playwright-based automation test project in seconds.
Note: This is a project scaffolding tool, not a library. Do not use
npm install create-please-test.
npm create please-test@latest my-projectThe built-in template is pre-configured against practicetestautomation.com/practice-test-login — runs out of the box with no extra setup.
What it does
create-please-test generates a ready-to-run E2E test project using:
- please-test — a readable Playwright wrapper
- @playwright/test — browser automation and test runner
Requirements
- Node.js >= 18
- Browser binary managed by Playwright (
npx playwright install <browser>)
Quick Start
# 1. Scaffold the project
npm create please-test my-project
# 2. Enter the directory
cd my-project
# 3. Install dependencies
npm install
# 4. Install Playwright browsers
npx playwright install chromium
# 5. Copy the environment file
cp .env.example .env.env is pre-filled with the default credentials for the practice site:
BASE_URL=https://practicetestautomation.com
ACCOUNT_USERNAME=student
ACCOUNT_PASSWORD=Password123
HEADLESS=true
BROWSER=chromiumHEADLESS—falseto run with a visible browser windowBROWSER—chromium,firefox, orwebkit(seeplaywright.config.js)
# 6. Run the tests
npm test
# (Optional) Open the HTML report
npm run reportGenerated Project Structure
my-project/
├── playwright.config.js # Playwright configuration
├── app.js # Factory function — creates please + components per test
├── package.json
├── jsconfig.json # Editor IntelliSense config
├── .env.example # Environment variable template
├── .gitignore
│
├── data/
│ └── main.js # Page URLs and test account data (reads from .env)
│
├── components/
│ └── auth.js # Reusable login/logout/assertion actions
│
├── feature/
│ ├── login.spec.js # Example login test suite (uses `please` directly)
│ └── login-using-component.spec.js # Same suite rewritten with `AUTH` component (skipped by default)
│
├── reporter/
│ └── please-reporter.js # Custom Playwright reporter — builds the HTML report
│
└── scripts/
└── open-report.js # Local static server for `npm run report`Template Tests: Login
The template includes 5 login scenarios against practicetestautomation.com:
| # | Scenario | Expected |
|---|----------|----------|
| 1 | Open login page | Page loads |
| 2 | Login with wrong username | Error: Your username is invalid! |
| 3 | Login with wrong password | Error: Your password is invalid! |
| 4 | Login with empty form | Error: Your username is invalid! |
| 5 | Successful login | Redirect to /logged-in-successfully/, heading Logged In Successfully visible |
How It Works
app.js — Per-test factory
const Please = require('please-test')
const Auth = require('./components/auth')
function createApp(page, test) {
const please = new Please(page, test)
return {
please,
AUTH: Auth(please)
}
}
module.exports = { createApp }Setiap test memanggil createApp(page, test) dengan page dan test dari Playwright fixture. Parameter test memungkinkan please-test melaporkan langkah-langkah sebagai test.step di HTML report. Ini memastikan setiap test berjalan terisolasi.
data/main.js — Pages and accounts
Values are read from .env via dotenv, so credentials never live in the source code.
require('dotenv').config({ path: require('path').join(__dirname, '..', '.env') })
module.exports = {
PAGE: {
login: {
url: `${process.env.BASE_URL}/practice-test-login/`,
title: 'Test Login | Practice Test Automation',
},
dashboard: {
url: `${process.env.BASE_URL}/logged-in-successfully/`,
title: 'Logged In Successfully | Practice Test Automation',
},
},
ACCOUNT: {
valid: { username: process.env.ACCOUNT_USERNAME, password: process.env.ACCOUNT_PASSWORD },
wrongPassword: { username: process.env.ACCOUNT_USERNAME, password: 'wrongpassword' },
wrongUsername: { username: 'invaliduser', password: process.env.ACCOUNT_PASSWORD },
empty: { username: '', password: '' },
},
}components/auth.js — Reusable actions
const { PAGE } = require('../data/main')
function Auth(please) {
return {
async goto() {
await please.goto(PAGE.login.url, PAGE.login.title)
},
async login(user) {
await please.fill('input username', '#username', user.username)
await please.fill('input password', '#password', user.password)
await please.click('button submit', '#submit')
},
async logout() {
await please.click('button logout', 'text=Log out')
},
async seeError(expected) {
return please.see('pesan error', '#error', expected)
},
async seeDashboard() {
await please.verifyPage(PAGE.dashboard.url, PAGE.dashboard.title)
return please.see('teks sukses', 'h1', 'Logged In Successfully')
}
}
}
module.exports = Authfeature/login.spec.js — Example test (uses please directly)
const { test } = require('@playwright/test')
const { createApp } = require('../app')
const { PAGE } = require('../data/main')
test.describe('Login', () => {
test('login berhasil', async ({ page }) => {
const { please } = createApp(page, test)
await please.goto(PAGE.login.url, PAGE.login.title)
await please.fill('input username', '#username', 'student')
await please.fill('input password', '#password', 'Password123')
await please.click('button submit', '#submit')
await please.verifyPage(PAGE.dashboard.url, PAGE.dashboard.title)
await please.see('teks sukses', 'h1', 'Logged In Successfully')
await please.click('button logout', 'text=Log out')
})
test('login gagal - username salah', async ({ page }) => {
const { please } = createApp(page, test)
await please.goto(PAGE.login.url, PAGE.login.title)
await please.fill('input username', '#username', 'wronguser')
await please.fill('input password', '#password', 'Password123')
await please.click('button submit', '#submit')
await please.see('pesan error', '#error', 'Your username is invalid!')
})
})Setiap test block mendapat page sendiri dari Playwright — tidak ada shared state antar test.
feature/login-using-component.spec.js — Same suite via AUTH component
The same scenarios rewritten using components/auth.js instead of calling please directly. This file is test.describe.skip by default — flip it to test.describe (and skip/remove the other spec) once you migrate to the component pattern.
const { test } = require('@playwright/test')
const { createApp } = require('../app')
const { ACCOUNT } = require('../data/main')
test.describe.skip('Login - using component', () => {
test('login berhasil', async ({ page }) => {
const { AUTH } = createApp(page, test)
await AUTH.goto()
await AUTH.login(ACCOUNT.valid)
await AUTH.seeDashboard()
await AUTH.logout()
})
test('login gagal - username salah', async ({ page }) => {
const { AUTH } = createApp(page, test)
await AUTH.goto()
await AUTH.login(ACCOUNT.wrongUsername)
await AUTH.seeError('Your username is invalid!')
})
})please-test API
| Method | Description |
|--------|-------------|
| please.goto(url, title?) | Navigasi ke URL, opsional verifikasi title |
| please.verifyPage(url, title?) | Verifikasi URL dan/atau title halaman saat ini |
| please.url() | Ambil URL halaman saat ini |
| please.title() | Ambil title halaman saat ini |
| please.click(label, selector, delay?) | Klik elemen |
| please.fill(label, selector, value) | Isi input field |
| please.fillAndEnter(label, selector, value) | Isi input field lalu tekan Enter |
| please.clear(label, selector) | Kosongkan input field |
| please.scrollTo(label, selector) | Scroll halaman ke posisi elemen |
| please.uploadFile(label, selector, filePath) | Upload file ke input type=file |
| please.datepicker(label, selector, value) | Isi date picker dengan format tanggal |
| please.see(label, selector, expected?, timeout?) | Ambil teks/nilai elemen, opsional assert |
| please.untilShow(label, selector, timeout?) | Tunggu elemen muncul (default 20 detik) |
| please.wait(ms?) | Pause eksekusi selama N milidetik |
| please.screenshot(label?) | Ambil screenshot, simpan ke folder screenshots/ |
| please.detectLocator(selector) | Deteksi tipe selector (id/class/text/role/xpath/dll) |
| please.toLocator(selector) | Konversi selector menjadi Playwright Locator |
Selector yang didukung
#id → CSS id
.class → CSS class
button=Name → role=button[name=Name] (shorthand ARIA)
text=... → teks konten
label=... → form label
role=... → ARIA role
//xpath → XPathAdding a New Feature Test
- Add URLs/data in
data/main.js - Create a component in
components/(e.g.components/checkout.js) - Write the spec in
feature/checkout.spec.js
Playwright otomatis menemukan semua file *.spec.js di folder feature/.
HTML Report
reporter/please-reporter.js is a custom Playwright reporter (registered in playwright.config.js) that collects every suite/test/step result and writes a self-contained HTML report to please-report/index.html after each run.
npm run report runs scripts/open-report.js, which serves that please-report/ folder on http://localhost:9323 and opens it in your default browser. It errors out if you haven't run npm test yet (no report to serve).
Scripts
| Command | Description |
|---------|-------------|
| npm test | Run all spec files, generate the HTML report |
| npm run report | Serve and open the last HTML report in your browser |
License
MIT © Myghan
