qaify-playwright-reporter 0.7.0 → 0.8.0

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.
package/README.md CHANGED
@@ -105,11 +105,15 @@ Untuk aplikasi yang repo FE dan BE-nya terpisah dan belum memasang Playwright, Q
105
105
 
106
106
  1. Pilih repo runner: repo kosong (mis. `qaify-runner`) atau repo aplikasinya sendiri. Jalankan `npx qaify-playwright-reporter init-runner` di dalamnya. Perintah ini menulis `.github/workflows/qaify-audit.yml`.
107
107
  2. Pasang GitHub App Qaify di repo runner, repo FE, dan repo BE.
108
- 3. Di repo runner, isi secret `QA_FACTORY_TOKEN` (token reporter repo runner), dan variable `QA_FACTORY_URL`. Secret `CLAUDE_CODE_OAUTH_TOKEN` bersifat opsional.
108
+ 3. Di repo runner, isi secret `QA_FACTORY_TOKEN` (token reporter repo runner), dan variable `QA_FACTORY_URL`. Secret `CLAUDE_CODE_OAUTH_TOKEN` bersifat opsional. Secret ini dibutuhkan untuk [perbaikan temuan oleh Claude](#perbaikan-temuan-audit-oleh-claude-pr-ke-repo-febe) dan audit mode Claude.
109
109
 
110
- - Tanpa secret itu, audit berjalan **tanpa AI** (`qaify audit-static`): build, test, `composer audit` / `npm audit`, route GET publik BE, dan smoke test Playwright FE (desktop + mobile, screenshot setiap halaman untuk lampiran laporan PDF). Smoke test juga memeriksa elemen yang meluap, gambar rusak, tombol yang tertutup elemen lain, error JavaScript, request API, dan aset yang gagal. Setiap jenis masalah difoto lagi dengan kotak merah di elemennya atau banner berisi pesan errornya. Temuan smoke diberi halaman dan berkas sumber bila bisa ditebak (route FE → komponen halaman, route BE → method controller). Request FE yang gagal dipetakan ke controller BE, dan route BE yang error dihubungkan ke halaman FE yang memanggilnya.
111
- - Dengan secret itu, Claude yang mengaudit. Hasilnya lebih dalam, termasuk logika bisnis dan kontrak API.
112
- - Mode bisa dipaksa lewat variable `QA_FACTORY_AUDIT_MODE` (`static` / `claude`).
110
+ Mode audit dipilih di Qaify: **Tanpa AI** (default) atau **Claude**, sebagai setelan aplikasi, dan bisa diganti di dialog **Audit sekarang**. Jadi Claude bisa dipakai hanya untuk memperbaiki temuan, sementara auditnya tetap tanpa AI. Mode Claude tanpa secret di atas dijalankan sebagai Tanpa AI (dengan peringatan di run).
111
+
112
+ - **Tanpa AI** (`qaify audit-static`): build, test, `composer audit` / `npm audit`, route GET publik BE, dan smoke test Playwright FE (desktop + mobile, screenshot setiap halaman untuk lampiran laporan PDF). Smoke test juga memeriksa elemen yang meluap, gambar rusak, tombol yang tertutup elemen lain, error JavaScript, request API, dan aset yang gagal. Setiap jenis masalah difoto lagi dengan kotak merah di elemennya atau banner berisi pesan errornya. Temuan smoke diberi halaman dan berkas sumber bila bisa ditebak (route FE → komponen halaman, route BE → method controller). Request FE yang gagal dipetakan ke controller BE, dan route BE yang error dihubungkan ke halaman FE yang memanggilnya.
113
+ - **Claude**: Claude yang mengaudit. Hasilnya lebih dalam, termasuk logika bisnis dan kontrak API, tetapi memakan kuota langganan.
114
+ - Variable `QA_FACTORY_AUDIT_MODE` (`static` / `claude`) hanya dipakai bila backend Qaify belum mengirim mode (versi lama).
115
+
116
+ Runner yang dibuat sebelum 0.8 perlu memperbarui workflow: `npx qaify-playwright-reporter init-runner --force`. Tanpa itu, workflow lama tetap memilih mode dari secret dan variable.
113
117
  4. Di Qaify → **Aplikasi**, tambahkan aplikasi (repo FE, BE, runner), lalu klik **Audit sekarang**.
114
118
 
115
119
  Alur di workflow:
@@ -128,7 +132,7 @@ Keamanan:
128
132
  - `QA_FACTORY_TOKEN` tidak tersedia di step Claude.
129
133
  - Isi repo diperlakukan sebagai data, bukan instruksi.
130
134
 
131
- Satu audit adalah satu sesi Claude yang panjang (sampai 45 menit), sehingga memakan kuota langganan pemilik runner.
135
+ Satu audit mode Claude adalah satu sesi Claude yang panjang (sampai 45 menit), sehingga memakan kuota langganan pemilik runner. Audit tanpa AI tidak memakai kuota.
132
136
 
133
137
  ## Perbaikan temuan audit oleh Claude (PR ke repo FE/BE)
134
138
 
package/dist/audit.d.ts CHANGED
@@ -279,9 +279,13 @@ export declare const defaultExec: Exec;
279
279
  export interface AuditContextResult {
280
280
  ok: boolean;
281
281
  commits: Record<string, string>;
282
+ /** auditor pilihan Qaify (static / claude); undefined = backend lama, workflow memilih sendiri */
283
+ mode?: AuditMode;
282
284
  /** alasan gagal; juga ditulis ke context-error.txt agar audit-submit bisa melaporkannya */
283
285
  error?: string;
284
286
  }
287
+ export declare const AUDIT_MODES: readonly ["static", "claude"];
288
+ export type AuditMode = (typeof AUDIT_MODES)[number];
285
289
  /**
286
290
  * GET /api/ingest/audits/{id}/context → clone apps/<role> → cabut token.
287
291
  * Token hanya lewat header git dari environment (tidak pernah di argumen, URL remote, atau disk)
package/dist/audit.js CHANGED
@@ -174,6 +174,7 @@ export function parseAuditOutput(raw) {
174
174
  const execFileAsync = promisify(execFile);
175
175
  export const defaultExec = async (file, args, env) => (await execFileAsync(file, args, { env: { ...process.env, ...env }, maxBuffer: 10 * 1024 * 1024 })).stdout;
176
176
  const branchOf = (repo) => repo.branch || repo.default_branch;
177
+ export const AUDIT_MODES = ['static', 'claude'];
177
178
  const CONTEXT_ERROR_FILE = 'context-error.txt';
178
179
  /**
179
180
  * GET /api/ingest/audits/{id}/context → clone apps/<role> → cabut token.
@@ -214,12 +215,14 @@ export async function auditContext(client, auditId, dir, opts = {}) {
214
215
  return contextFailed(dir, `Clone repo gagal: ${detail}`, commits);
215
216
  }
216
217
  await revoke(repos, opts.fetch);
218
+ const mode = AUDIT_MODES.includes(ctx.mode) ? ctx.mode : undefined;
217
219
  await writeFile(join(dir, 'context.json'), JSON.stringify({
218
220
  audit_id: ctx.audit_id,
221
+ mode: mode ?? null,
219
222
  project: ctx.project,
220
223
  repos: repos.map((r) => ({ role: r.role, full_name: r.full_name, branch: branchOf(r), commit: commits[r.role] ?? null })),
221
224
  }, null, 2));
222
- return { ok: true, commits };
225
+ return { ok: true, commits, mode };
223
226
  }
224
227
  /** Peringatan (annotation di ringkasan run) + context-error.txt untuk audit-submit. */
225
228
  async function contextFailed(dir, error, commits) {
package/dist/cli.js CHANGED
@@ -137,8 +137,9 @@ switch (args.command) {
137
137
  // step merah: tanpa ini auditor & kirim hasil dilewati diam-diam dan audit macet "running"
138
138
  process.exitCode = 1;
139
139
  }
140
+ // mode kosong = backend lama: workflow memilih dari variable / secret
140
141
  if (process.env.GITHUB_OUTPUT)
141
- await appendFile(process.env.GITHUB_OUTPUT, `ok=${result.ok}\n`);
142
+ await appendFile(process.env.GITHUB_OUTPUT, `ok=${result.ok}\nmode=${('mode' in result && result.mode) || ''}\n`);
142
143
  break;
143
144
  }
144
145
  case 'audit-schema': {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qaify-playwright-reporter",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Reporter Playwright untuk QA Factory (Qaify): kirim hasil test dan artefak ke /api/ingest, tanpa pernah menggagalkan test.",
5
5
  "license": "MIT",
6
6
  "author": "ahmdkenz",
@@ -3,13 +3,14 @@
3
3
  # Butuh di repo runner ini (Settings → Secrets and variables → Actions):
4
4
  # secret QA_FACTORY_TOKEN token reporter repo runner (Pengaturan → Token Reporter)
5
5
  # variable QA_FACTORY_URL URL API Qaify
6
- # secret CLAUDE_CODE_OAUTH_TOKEN opsional: audit dengan Claude (langganan Claude Pro/Max Anda, `claude setup-token`)
7
- # variable QA_FACTORY_AUDIT_MODE opsional, `static` atau `claude` (default: claude bila secret di atas ada)
6
+ # secret CLAUDE_CODE_OAUTH_TOKEN opsional: perbaikan temuan & audit mode claude (langganan Claude Pro/Max, `claude setup-token`)
7
+ # variable QA_FACTORY_AUDIT_MODE opsional, `static` / `claude`; hanya dipakai bila Qaify tidak mengirim mode
8
8
  # variable QA_FACTORY_AI_MODEL opsional, default sonnet
9
9
  # variable QA_FACTORY_MCP_VERSION opsional, versi @playwright/mcp (default latest)
10
10
  # GitHub App Qaify harus terpasang di repo ini dan di repo FE + BE. Nama file harus tetap qaify-audit.yml.
11
+ # Mode audit dipilih di Qaify (setelan aplikasi, bisa diganti per audit); mode claude tanpa secret jatuh ke static.
11
12
  # Mode static (tanpa AI): build, test, composer/npm audit, dan smoke test Playwright; cepat, tanpa kuota AI,
12
- # tetapi tanpa analisis logika bisnis / kontrak API dari kode.
13
+ # tetapi tanpa analisis logika bisnis / kontrak API dari kode. Temuannya tetap bisa diperbaiki Claude (qaify-fix.yml).
13
14
  # Mode claude: satu sesi Claude yang panjang; kuota langganan dipakai bersama pemakaian pribadi.
14
15
  name: Qaify audit
15
16
  run-name: audit ${{ inputs.audit_id }}
@@ -42,9 +43,8 @@ jobs:
42
43
  env: { POSTGRES_PASSWORD: postgres, POSTGRES_DB: app }
43
44
  ports: ['5432:5432']
44
45
  options: --health-cmd="pg_isready -U postgres" --health-interval=10s --health-timeout=5s --health-retries=10
45
- # context runner tidak tersedia di env level job; WORK diisi lewat GITHUB_ENV di step pertama
46
- env:
47
- AUDIT_MODE: ${{ vars.QA_FACTORY_AUDIT_MODE || (secrets.CLAUDE_CODE_OAUTH_TOKEN != '' && 'claude' || 'static') }}
46
+ # context runner tidak tersedia di env level job; WORK diisi lewat GITHUB_ENV di step pertama,
47
+ # AUDIT_MODE di step "Tentukan mode audit" (mode baru diketahui dari konteks audit)
48
48
  steps:
49
49
  - name: Siapkan direktori kerja
50
50
  run: echo "WORK=$RUNNER_TEMP/qaify" >> "$GITHUB_ENV"
@@ -58,9 +58,7 @@ jobs:
58
58
  tools: composer
59
59
 
60
60
  - name: Pasang Qaify CLI
61
- run: |
62
- npm install -g qaify-playwright-reporter@0.5 playwright-core@1
63
- if [ "$AUDIT_MODE" = claude ]; then npm install -g @anthropic-ai/claude-code; fi
61
+ run: npm install -g qaify-playwright-reporter@0.8 playwright-core@1
64
62
 
65
63
  # token clone sekali pakai (read-only, hanya repo FE + BE) dicabut sebelum auditor berjalan
66
64
  - name: Ambil konteks & clone repo FE + BE
@@ -70,6 +68,25 @@ jobs:
70
68
  QA_FACTORY_TOKEN: ${{ secrets.QA_FACTORY_TOKEN }}
71
69
  run: qaify audit-context --audit "${{ inputs.audit_id }}" --dir "$WORK"
72
70
 
71
+ # pilihan Qaify → variable QA_FACTORY_AUDIT_MODE → claude bila secret ada; claude tanpa secret → static
72
+ - name: Tentukan mode audit
73
+ if: steps.ctx.outputs.ok == 'true'
74
+ env:
75
+ REQUESTED: ${{ steps.ctx.outputs.mode || vars.QA_FACTORY_AUDIT_MODE }}
76
+ HAS_CLAUDE: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN != '' }}
77
+ run: |
78
+ mode="${REQUESTED:-$([ "$HAS_CLAUDE" = true ] && echo claude || echo static)}"
79
+ if [ "$mode" != static ] && [ "$mode" != claude ]; then
80
+ echo "::warning::Mode audit tidak dikenal ($mode); memakai static."
81
+ mode=static
82
+ fi
83
+ if [ "$mode" = claude ] && [ "$HAS_CLAUDE" != true ]; then
84
+ echo "::warning::Mode claude diminta tetapi secret CLAUDE_CODE_OAUTH_TOKEN kosong; audit dijalankan tanpa AI."
85
+ mode=static
86
+ fi
87
+ echo "qa-factory: mode audit $mode"
88
+ echo "AUDIT_MODE=$mode" >> "$GITHUB_ENV"
89
+
73
90
  # tanpa secret apa pun: kode aplikasi (composer/npm script) berjalan di step ini
74
91
  - name: Audit tanpa AI (Playwright)
75
92
  if: steps.ctx.outputs.ok == 'true' && env.AUDIT_MODE == 'static'
@@ -80,6 +97,7 @@ jobs:
80
97
  - name: Siapkan instruksi & Playwright MCP
81
98
  if: steps.ctx.outputs.ok == 'true' && env.AUDIT_MODE == 'claude'
82
99
  run: |
100
+ npm install -g @anthropic-ai/claude-code
83
101
  mkdir -p "$WORK/.qaify"
84
102
  qaify audit-schema --out "$WORK/.qaify/schema.json" --instructions "$WORK/.qaify/instructions.txt"
85
103
  # Google Chrome sudah ada di runner ubuntu-latest