@mechris3/glassbox 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +94 -1
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -76,6 +76,28 @@ Either way, run `glassbox` commands from the directory containing your `glassbox
76
76
  - Node.js 20+
77
77
  - A Chromium-based browser (Chrome, Brave, Edge)
78
78
 
79
+ ## Environment Variables
80
+
81
+ Config files, hooks, journeys, and page objects are all TypeScript running in Node — `process.env` works everywhere:
82
+
83
+ ```typescript
84
+ // page-objects/login.page.ts — credentials from env
85
+ async login() {
86
+ const user = process.env.TEST_USERNAME ?? 'default@test.com';
87
+ const pass = process.env.TEST_PASSWORD ?? 'password123';
88
+ await this.fill('[data-testid="email"]', user);
89
+ await this.fill('[data-testid="password"]', pass);
90
+ await this.click('[data-testid="submit"]');
91
+ }
92
+
93
+ // glassbox.config.ts — headless in CI
94
+ browser: { headless: process.env.CI === 'true' }
95
+
96
+ // helpers/before-each.ts — API key for test data service
97
+ const apiKey = process.env.TEST_API_KEY;
98
+ await fetch('http://...', { headers: { Authorization: `Bearer ${apiKey}` } });
99
+ ```
100
+
79
101
  ## Consumer Usage
80
102
 
81
103
  ### Page Objects
@@ -157,7 +179,78 @@ export default defineConfig({
157
179
  });
158
180
  ```
159
181
 
160
- ### Lifecycle Hooks
182
+ ### Best Practices
183
+
184
+ ### Journeys are pure orchestration
185
+
186
+ A journey's `execute()` method should contain **only** calls to page object methods — no conditionals, no assertions, no direct selectors:
187
+
188
+ ```typescript
189
+ // Good — reads like a user story
190
+ async execute() {
191
+ await this.loginPage.loginAs('alice@company.com', 'alice123');
192
+ await this.dashboardPage.verifyLoaded();
193
+ await this.dashboardPage.navigateToProjects();
194
+ await this.projectsPage.verifyProjectCount(6);
195
+ }
196
+
197
+ // Bad — logic leaking into journey
198
+ async execute() {
199
+ await this.fill('[data-testid="email"]', 'alice@company.com');
200
+ const count = await this.getText('[data-testid="count"]');
201
+ if (parseInt(count) !== 6) throw new Error('wrong');
202
+ }
203
+ ```
204
+
205
+ ### Page objects own everything
206
+
207
+ - **Selectors** — store in a private `selectors` object, never expose them
208
+ - **Interaction** — `loginAs()`, `addTask()`, `filterByStatus()` — intention-revealing names
209
+ - **Validation** — `verifyLoaded()`, `verifyErrorMessage()`, `verifyTaskCount()` — throw descriptive errors on failure
210
+
211
+ ```typescript
212
+ export class ProjectsPage extends BasePage {
213
+ private selectors = {
214
+ projectCard: '[data-testid="project-card"]',
215
+ filterActive: '[data-testid="filter-active"]',
216
+ count: '[data-testid="project-count"]',
217
+ };
218
+
219
+ async filterByActive() {
220
+ await this.click(this.selectors.filterActive);
221
+ }
222
+
223
+ async verifyProjectCount(expected: number) {
224
+ const count = await this.getText(this.selectors.count);
225
+ if (count !== String(expected)) {
226
+ throw new Error(`Expected ${expected} projects, got ${count}`);
227
+ }
228
+ }
229
+ }
230
+ ```
231
+
232
+ ### Selector strategy
233
+
234
+ - Always use `[data-testid="..."]` — never CSS classes, tag names, or DOM structure
235
+ - For repeated items, include an identifier: `[data-testid="task-item-${id}"]`
236
+ - If an element doesn't have a `data-testid`, add one to your app first
237
+
238
+ ### File organisation
239
+
240
+ ```
241
+ glassbox/
242
+ ├── page-objects/
243
+ │ ├── login.page.ts ← one class per file
244
+ │ ├── dashboard.page.ts
245
+ │ └── projects.page.ts
246
+ ├── journeys/
247
+ │ ├── login-and-browse.journey.ts
248
+ │ └── create-task.journey.ts
249
+ └── helpers/
250
+ └── before-each.ts
251
+ ```
252
+
253
+ ## Lifecycle Hooks
161
254
 
162
255
  Run code before/after journeys for test data setup and cleanup:
163
256
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mechris3/glassbox",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Debugger-style browser automation test runner with live execution control via CDP",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",