-
Notifications
You must be signed in to change notification settings - Fork 0
Re work #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Zir0-93
wants to merge
19
commits into
master
Choose a base branch
from
re-work
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Re work #4
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
9a8000c
initial changes for rework.
Zir0-93 13a9eb7
lastest changes
fbb7b85
A lot of stuff
Zir0-93 a200829
A lot of stuff
Zir0-93 ad0f942
Fix more stuff
Zir0-93 4c981ad
Fix stuff
Zir0-93 2b0a79f
Latest stuff
Zir0-93 ab9d022
updates
Zir0-93 ff4fda0
Fix live smoke flows and cache persistence
Zir0-93 3592568
Fix live file-tree mapping coverage
Zir0-93 1968537
Fix file detection and update supported extensions
Zir0-93 0abdb5b
Rework: UI improvements, toast styling, Turbo cache fix, engagement t…
Zir0-93 553d4e3
Copy-to-clipboard for review notes, fix file tree disabling on cache …
Zir0-93 6533e02
fix: recognize surfaced_note_ prefix as AI review note
Zir0-93 f4a214c
feat: recognize surfaced_note_ aliases in review note detection
Zir0-93 b7e3d51
fix: switch to Write tab before giving up on hidden textarea in revie…
Zir0-93 52aece3
fix: derive risk badge from surfacedItems instead of retired riskLevel
Zir0-93 6bf1004
chore: add lint/format config, changelog, and review docs; drop scrat…
Zir0-93 2b6f6a7
Rework: persistent token storage, PlantUML utils, UI polish, and test…
Zir0-93 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| { | ||
| "name": "playwright-skill", | ||
| "version": "4.1.0", | ||
| "description": "General-purpose browser automation with Playwright for Claude Code with auto-detection and smart test management", | ||
| "author": "lackeyjb", | ||
| "main": "run.js", | ||
| "scripts": { | ||
| "setup": "npm install && npx playwright install chromium", | ||
| "install-all-browsers": "npx playwright install chromium firefox webkit" | ||
| }, | ||
| "keywords": [ | ||
| "playwright", | ||
| "automation", | ||
| "browser-testing", | ||
| "web-automation", | ||
| "claude-skill", | ||
| "general-purpose" | ||
| ], | ||
| "dependencies": { | ||
| "playwright": "^1.57.0" | ||
| }, | ||
| "engines": { | ||
| "node": ">=14.0.0" | ||
| }, | ||
| "license": "MIT" | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,228 @@ | ||
| #!/usr/bin/env node | ||
| /** | ||
| * Universal Playwright Executor for Claude Code | ||
| * | ||
| * Executes Playwright automation code from: | ||
| * - File path: node run.js script.js | ||
| * - Inline code: node run.js 'await page.goto("...")' | ||
| * - Stdin: cat script.js | node run.js | ||
| * | ||
| * Ensures proper module resolution by running from skill directory. | ||
| */ | ||
|
|
||
| const fs = require('fs'); | ||
| const path = require('path'); | ||
| const { execSync } = require('child_process'); | ||
|
|
||
| // Change to skill directory for proper module resolution | ||
| process.chdir(__dirname); | ||
|
|
||
| /** | ||
| * Check if Playwright is installed | ||
| */ | ||
| function checkPlaywrightInstalled() { | ||
| try { | ||
| require.resolve('playwright'); | ||
| return true; | ||
| } catch (e) { | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Install Playwright if missing | ||
| */ | ||
| function installPlaywright() { | ||
| console.log('📦 Playwright not found. Installing...'); | ||
| try { | ||
| execSync('npm install', { stdio: 'inherit', cwd: __dirname }); | ||
| execSync('npx playwright install chromium', { stdio: 'inherit', cwd: __dirname }); | ||
| console.log('✅ Playwright installed successfully'); | ||
| return true; | ||
| } catch (e) { | ||
| console.error('❌ Failed to install Playwright:', e.message); | ||
| console.error('Please run manually: cd', __dirname, '&& npm run setup'); | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Get code to execute from various sources | ||
| */ | ||
| function getCodeToExecute() { | ||
| const args = process.argv.slice(2); | ||
|
|
||
| // Case 1: File path provided | ||
| if (args.length > 0 && fs.existsSync(args[0])) { | ||
| const filePath = path.resolve(args[0]); | ||
| console.log(`📄 Executing file: ${filePath}`); | ||
| return fs.readFileSync(filePath, 'utf8'); | ||
| } | ||
|
|
||
| // Case 2: Inline code provided as argument | ||
| if (args.length > 0) { | ||
| console.log('⚡ Executing inline code'); | ||
| return args.join(' '); | ||
| } | ||
|
|
||
| // Case 3: Code from stdin | ||
| if (!process.stdin.isTTY) { | ||
| console.log('📥 Reading from stdin'); | ||
| return fs.readFileSync(0, 'utf8'); | ||
| } | ||
|
|
||
| // No input | ||
| console.error('❌ No code to execute'); | ||
| console.error('Usage:'); | ||
| console.error(' node run.js script.js # Execute file'); | ||
| console.error(' node run.js "code here" # Execute inline'); | ||
| console.error(' cat script.js | node run.js # Execute from stdin'); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| /** | ||
| * Clean up old temporary execution files from previous runs | ||
| */ | ||
| function cleanupOldTempFiles() { | ||
| try { | ||
| const files = fs.readdirSync(__dirname); | ||
| const tempFiles = files.filter(f => f.startsWith('.temp-execution-') && f.endsWith('.js')); | ||
|
|
||
| if (tempFiles.length > 0) { | ||
| tempFiles.forEach(file => { | ||
| const filePath = path.join(__dirname, file); | ||
| try { | ||
| fs.unlinkSync(filePath); | ||
| } catch (e) { | ||
| // Ignore errors - file might be in use or already deleted | ||
| } | ||
| }); | ||
| } | ||
| } catch (e) { | ||
| // Ignore directory read errors | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Wrap code in async IIFE if not already wrapped | ||
| */ | ||
| function wrapCodeIfNeeded(code) { | ||
| // Check if code already has require() and async structure | ||
| const hasRequire = code.includes('require('); | ||
| const hasAsyncIIFE = code.includes('(async () => {') || code.includes('(async()=>{'); | ||
|
|
||
| // If it's already a complete script, return as-is | ||
| if (hasRequire && hasAsyncIIFE) { | ||
| return code; | ||
| } | ||
|
|
||
| // If it's just Playwright commands, wrap in full template | ||
| if (!hasRequire) { | ||
| return ` | ||
| const { chromium, firefox, webkit, devices } = require('playwright'); | ||
| const helpers = require('./lib/helpers'); | ||
|
|
||
| // Extra headers from environment variables (if configured) | ||
| const __extraHeaders = helpers.getExtraHeadersFromEnv(); | ||
|
|
||
| /** | ||
| * Utility to merge environment headers into context options. | ||
| * Use when creating contexts with raw Playwright API instead of helpers.createContext(). | ||
| * @param {Object} options - Context options | ||
| * @returns {Object} Options with extraHTTPHeaders merged in | ||
| */ | ||
| function getContextOptionsWithHeaders(options = {}) { | ||
| if (!__extraHeaders) return options; | ||
| return { | ||
| ...options, | ||
| extraHTTPHeaders: { | ||
| ...__extraHeaders, | ||
| ...(options.extraHTTPHeaders || {}) | ||
| } | ||
| }; | ||
| } | ||
|
|
||
| (async () => { | ||
| try { | ||
| ${code} | ||
| } catch (error) { | ||
| console.error('❌ Automation error:', error.message); | ||
| if (error.stack) { | ||
| console.error(error.stack); | ||
| } | ||
| process.exit(1); | ||
| } | ||
| })(); | ||
| `; | ||
| } | ||
|
|
||
| // If has require but no async wrapper | ||
| if (!hasAsyncIIFE) { | ||
| return ` | ||
| (async () => { | ||
| try { | ||
| ${code} | ||
| } catch (error) { | ||
| console.error('❌ Automation error:', error.message); | ||
| if (error.stack) { | ||
| console.error(error.stack); | ||
| } | ||
| process.exit(1); | ||
| } | ||
| })(); | ||
| `; | ||
| } | ||
|
|
||
| return code; | ||
| } | ||
|
|
||
| /** | ||
| * Main execution | ||
| */ | ||
| async function main() { | ||
| console.log('🎭 Playwright Skill - Universal Executor\n'); | ||
|
|
||
| // Clean up old temp files from previous runs | ||
| cleanupOldTempFiles(); | ||
|
|
||
| // Check Playwright installation | ||
| if (!checkPlaywrightInstalled()) { | ||
| const installed = installPlaywright(); | ||
| if (!installed) { | ||
| process.exit(1); | ||
| } | ||
| } | ||
|
|
||
| // Get code to execute | ||
| const rawCode = getCodeToExecute(); | ||
| const code = wrapCodeIfNeeded(rawCode); | ||
|
|
||
| // Create temporary file for execution | ||
| const tempFile = path.join(__dirname, `.temp-execution-${Date.now()}.js`); | ||
|
|
||
| try { | ||
| // Write code to temp file | ||
| fs.writeFileSync(tempFile, code, 'utf8'); | ||
|
|
||
| // Execute the code | ||
| console.log('🚀 Starting automation...\n'); | ||
| require(tempFile); | ||
|
|
||
| // Note: Temp file will be cleaned up on next run | ||
| // This allows long-running async operations to complete safely | ||
|
|
||
| } catch (error) { | ||
| console.error('❌ Execution failed:', error.message); | ||
| if (error.stack) { | ||
| console.error('\n📋 Stack trace:'); | ||
| console.error(error.stack); | ||
| } | ||
| process.exit(1); | ||
| } | ||
| } | ||
|
|
||
| // Run main function | ||
| main().catch(error => { | ||
| console.error('❌ Fatal error:', error.message); | ||
| process.exit(1); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| { | ||
| "root": true, | ||
| "env": { | ||
| "browser": true, | ||
| "es2022": true, | ||
| "node": true | ||
| }, | ||
| "extends": [], | ||
| "parserOptions": { | ||
| "ecmaVersion": "latest", | ||
| "sourceType": "script" | ||
| }, | ||
| "rules": { | ||
| "no-unused-vars": "warn", | ||
| "no-empty": ["warn", { "allowEmptyCatch": true }], | ||
| "no-console": ["warn", { "allow": ["warn", "error"] }] | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,40 @@ | ||
| .vscode/ | ||
| # IDE | ||
| .vscode/ | ||
| .idea/ | ||
|
|
||
| # Test artifacts | ||
| test/.pw-profile/ | ||
| .pw-profile/ | ||
| test/.pw-*/ | ||
| test/.pw-profile-*/ | ||
| test-results/ | ||
| dist/ | ||
|
|
||
| # Scratch / probe scripts and tool run artifacts | ||
| .tmp-* | ||
| .claude/scheduled_tasks.lock | ||
| .claude/**/.temp-execution-*.js | ||
|
|
||
| # Node | ||
| node_modules/ | ||
| *.log | ||
| npm-debug.log* | ||
| yarn-debug.log* | ||
| yarn-error.log* | ||
|
|
||
| # OS | ||
| .DS_Store | ||
| Thumbs.db | ||
|
|
||
| # Build | ||
| *.zip | ||
| build/ | ||
| dist/ | ||
|
|
||
| # Local config (test-only) | ||
| html/config-local-test.json | ||
|
|
||
| # Dev screenshots | ||
| preview-menu.png | ||
| *.png | ||
| !icons/*.png | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| { | ||
| "semi": true, | ||
| "singleQuote": true, | ||
| "trailingComma": "es5" | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ignore patterns only match
test/.pw-*at one directory depth, but this commit adds profile data undertest/test/.pw-profile-debug*(including Cookies/Login Data databases). Because those paths are not ignored, future local test runs will keep committing machine-specific browser state and potentially more credentials. Update the pattern to match nested profile paths as well.Useful? React with 👍 / 👎.