demo-reel 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,158 @@
1
+ # Demo Reel
2
+
3
+ Create beautiful demo videos from web apps using Playwright. Perfect for showcasing features, creating onboarding tutorials, or documenting workflows.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -D demo-reel playwright
9
+ ```
10
+
11
+ Or use without installing:
12
+
13
+ ```bash
14
+ npx demo-reel --config ./my-demo.ts
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ 1. Create a config file `demo-reel.config.ts`:
20
+
21
+ ```typescript
22
+ import { defineConfig } from 'demo-reel';
23
+
24
+ export default defineConfig({
25
+ viewport: { width: 1920, height: 1080 },
26
+ video: {
27
+ enabled: true,
28
+ size: { width: 1920, height: 1080 },
29
+ },
30
+ name: 'my-demo',
31
+ steps: [
32
+ { action: 'goto', url: 'https://example.com' },
33
+ { action: 'wait', ms: 2000 },
34
+ ],
35
+ });
36
+ ```
37
+
38
+ 2. Run it:
39
+
40
+ ```bash
41
+ npx demo-reel
42
+ ```
43
+
44
+ ## CLI Usage
45
+
46
+ ```bash
47
+ # Run default config (demo-reel.config.ts)
48
+ npx demo-reel
49
+
50
+ # Run a specific scenario
51
+ npx demo-reel onboarding
52
+
53
+ # Run all scenarios
54
+ npx demo-reel --all
55
+
56
+ # Dry run (validate config)
57
+ npx demo-reel --dry-run
58
+
59
+ # Show browser window (non-headless)
60
+ npx demo-reel --headed
61
+
62
+ # Override output directory
63
+ npx demo-reel --output-dir ./public/videos
64
+ ```
65
+
66
+ ## Configuration
67
+
68
+ ### Config File Discovery
69
+
70
+ The CLI looks for configs in this order:
71
+ 1. `demo-reel.config.ts` (default)
72
+ 2. `<scenario>.demo.ts` (when specifying a scenario name)
73
+ 3. All `*.demo.ts` files (with `--all` flag)
74
+
75
+ ### Output Naming
76
+
77
+ Videos are named based on this priority:
78
+ 1. `outputPath` in config (full path)
79
+ 2. `name` + `outputDir` in config
80
+ 3. Config filename (e.g., `onboarding.demo.ts` → `onboarding.webm`)
81
+ 4. Default: `demo-reel.webm`
82
+
83
+ ### Available Steps
84
+
85
+ - `goto` - Navigate to URL
86
+ - `click` - Click an element
87
+ - `hover` - Hover over element
88
+ - `type` - Type text into input
89
+ - `press` - Press a key
90
+ - `scroll` - Scroll element
91
+ - `select` - Select option(s)
92
+ - `check` - Check/uncheck checkbox
93
+ - `upload` - Upload file(s)
94
+ - `drag` - Drag element to target
95
+ - `wait` - Wait for duration
96
+ - `waitFor` - Wait for condition (selector, URL, loadState, request, response, function)
97
+
98
+ ### Selector Strategies
99
+
100
+ ```typescript
101
+ // By test ID (data-testid attribute)
102
+ { strategy: 'testId', value: 'submit-button' }
103
+
104
+ // By ID (without #)
105
+ { strategy: 'id', value: 'username' }
106
+
107
+ // By class (without .)
108
+ { strategy: 'class', value: 'btn-primary' }
109
+
110
+ // By href
111
+ { strategy: 'href', value: '/dashboard' }
112
+ ```
113
+
114
+ ## CI/CD Integration
115
+
116
+ Example GitHub Actions workflow:
117
+
118
+ ```yaml
119
+ name: Generate Demo Videos
120
+
121
+ on: push
122
+
123
+ jobs:
124
+ demos:
125
+ runs-on: ubuntu-latest
126
+ steps:
127
+ - uses: actions/checkout@v4
128
+ - uses: actions/setup-node@v4
129
+ with:
130
+ node-version: '20'
131
+ - run: npm ci
132
+ - run: npx playwright install chromium
133
+ - run: npx demo-reel --all
134
+ - uses: actions/upload-artifact@v4
135
+ with:
136
+ name: demo-videos
137
+ path: ./videos/*.webm
138
+ ```
139
+
140
+ ## Features
141
+
142
+ ### Human-Like Cursor Movement
143
+ - Smooth Bezier curve paths with ease-in/out timing
144
+ - Configurable speed, curve offset, and step count
145
+ - Visual cursor overlay (SVG or dot style)
146
+
147
+ ### Natural Typing
148
+ - Variable delays based on character type
149
+ - Longer pauses for spaces, punctuation, and newlines
150
+
151
+ ### Smart Delays
152
+ - Built-in delays after page navigation
153
+ - Per-step delays before/after actions
154
+ - Final delay to keep video open
155
+
156
+ ## License
157
+
158
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env node
2
+ import { loadConfig, findConfig, loadScenario, findScenarioFiles } from './config-loader.js';
3
+ import { runVideoScenario } from './video-handler.js';
4
+ function parseArgs() {
5
+ const args = process.argv.slice(2);
6
+ const options = {
7
+ verbose: false,
8
+ dryRun: false,
9
+ all: false,
10
+ };
11
+ let scenario;
12
+ for (let i = 0; i < args.length; i++) {
13
+ const arg = args[i];
14
+ if (arg === '--verbose' || arg === '-v') {
15
+ options.verbose = true;
16
+ }
17
+ else if (arg === '--dry-run') {
18
+ options.dryRun = true;
19
+ }
20
+ else if (arg === '--all') {
21
+ options.all = true;
22
+ }
23
+ else if (arg === '--output-dir' || arg === '-o') {
24
+ options.outputDir = args[++i];
25
+ }
26
+ else if (arg === '--headed') {
27
+ options.headed = true;
28
+ }
29
+ else if (arg === '--help' || arg === '-h') {
30
+ showHelp();
31
+ process.exit(0);
32
+ }
33
+ else if (!arg.startsWith('-')) {
34
+ scenario = arg;
35
+ }
36
+ }
37
+ return { scenario, options };
38
+ }
39
+ function showHelp() {
40
+ console.log(`
41
+ demo-reel - Create demo videos from web apps
42
+
43
+ Usage:
44
+ demo-reel [scenario] [options]
45
+
46
+ Arguments:
47
+ scenario Name of scenario to run (e.g., "onboarding")
48
+ Looks for: <scenario>.demo.ts or <scenario>.config.ts
49
+
50
+ Options:
51
+ --all Run all *.demo.ts files in the project
52
+ --output-dir, -o <dir> Override output directory for videos
53
+ --dry-run Validate config without recording
54
+ --headed Show browser window (non-headless)
55
+ --verbose, -v Show detailed output
56
+ --help, -h Show this help message
57
+
58
+ Examples:
59
+ demo-reel # Run demo-reel.config.ts
60
+ demo-reel onboarding # Run onboarding.demo.ts
61
+ demo-reel --all # Run all *.demo.ts files
62
+ demo-reel --dry-run # Validate config without recording
63
+ demo-reel -o ./public/videos # Override output directory
64
+ `);
65
+ }
66
+ async function main() {
67
+ const { scenario, options } = parseArgs();
68
+ try {
69
+ if (options.all) {
70
+ // Run all demo scenarios
71
+ const files = await findScenarioFiles();
72
+ if (files.length === 0) {
73
+ console.error('No *.demo.ts files found');
74
+ process.exit(1);
75
+ }
76
+ console.log(`Found ${files.length} scenario(s)`);
77
+ for (const file of files) {
78
+ console.log(`\n▶ ${file}`);
79
+ const loaded = await loadConfig(file, options.outputDir);
80
+ await runVideoScenario(loaded.config, loaded.outputPath, options);
81
+ }
82
+ }
83
+ else if (scenario) {
84
+ // Run specific scenario
85
+ const configPath = await loadScenario(scenario);
86
+ if (!configPath) {
87
+ console.error(`Scenario not found: ${scenario}`);
88
+ console.error('Looked for:');
89
+ console.error(` - ${scenario}.demo.ts`);
90
+ console.error(` - ${scenario}.config.ts`);
91
+ process.exit(1);
92
+ }
93
+ const loaded = await loadConfig(configPath, options.outputDir);
94
+ await runVideoScenario(loaded.config, loaded.outputPath, options);
95
+ }
96
+ else {
97
+ // Run default config
98
+ const configPath = await findConfig();
99
+ if (!configPath) {
100
+ console.error('No config file found. Looked for:');
101
+ console.error(' - demo-reel.config.ts');
102
+ console.error(' - demo-reel.config.js');
103
+ console.error(' - demo-reel.config.mjs');
104
+ console.error(' - demo-reel.config.json');
105
+ console.error('\nRun with --help for more options.');
106
+ process.exit(1);
107
+ }
108
+ const loaded = await loadConfig(configPath, options.outputDir);
109
+ await runVideoScenario(loaded.config, loaded.outputPath, options);
110
+ }
111
+ process.exit(0);
112
+ }
113
+ catch (error) {
114
+ if (options.verbose) {
115
+ console.error(error);
116
+ }
117
+ else {
118
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
119
+ }
120
+ process.exit(1);
121
+ }
122
+ }
123
+ main();
124
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { type DemoReelConfig } from './schemas.js';
2
+ export interface LoadedConfig {
3
+ config: DemoReelConfig;
4
+ configPath: string;
5
+ outputPath: string;
6
+ }
7
+ export declare function loadConfig(configPath: string, cliOutputDir?: string): Promise<LoadedConfig>;
8
+ export declare function findConfig(cwd?: string): Promise<string | null>;
9
+ export declare function findScenarioFiles(cwd?: string, pattern?: string): Promise<string[]>;
10
+ export declare function loadScenario(name: string, cwd?: string): Promise<string | null>;
11
+ //# sourceMappingURL=config-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAEzE,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AA+DD,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,YAAY,CAAC,CAavB;AAED,wBAAsB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgBpF;AAED,wBAAsB,iBAAiB,CACrC,GAAG,GAAE,MAAsB,EAC3B,OAAO,GAAE,MAAuB,GAC/B,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnB;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkBxB"}
@@ -0,0 +1,107 @@
1
+ import { promises as fs } from 'fs';
2
+ import { join, dirname, resolve, extname, basename } from 'path';
3
+ import { pathToFileURL } from 'url';
4
+ import { demoReelConfigSchema } from './schemas.js';
5
+ async function fileExists(path) {
6
+ try {
7
+ await fs.access(path);
8
+ return true;
9
+ }
10
+ catch {
11
+ return false;
12
+ }
13
+ }
14
+ async function loadConfigFile(configPath) {
15
+ const ext = extname(configPath);
16
+ if (ext === '.ts') {
17
+ // For TypeScript files, we'll try to use dynamic import with tsx
18
+ // In a real implementation, we'd need to handle this better
19
+ // For now, we'll throw an error suggesting the build process
20
+ const module = await import(pathToFileURL(configPath).href);
21
+ const config = module.default || module;
22
+ return demoReelConfigSchema.parse(config);
23
+ }
24
+ if (ext === '.js' || ext === '.mjs') {
25
+ const module = await import(pathToFileURL(configPath).href);
26
+ const config = module.default || module;
27
+ return demoReelConfigSchema.parse(config);
28
+ }
29
+ if (ext === '.json') {
30
+ const content = await fs.readFile(configPath, 'utf-8');
31
+ const config = JSON.parse(content);
32
+ return demoReelConfigSchema.parse(config);
33
+ }
34
+ throw new Error(`Unsupported config file extension: ${ext}`);
35
+ }
36
+ function resolveOutputPath(config, configPath, cliOutputDir) {
37
+ // Priority 1: outputPath from config
38
+ if (config.outputPath) {
39
+ if (config.outputPath.startsWith('/')) {
40
+ return config.outputPath;
41
+ }
42
+ return resolve(dirname(configPath), config.outputPath);
43
+ }
44
+ // Priority 2: name + outputDir (or CLI override)
45
+ const outputDir = cliOutputDir || config.outputDir || dirname(configPath);
46
+ const baseName = config.name || getBaseNameFromConfig(configPath);
47
+ return join(resolve(outputDir), `${baseName}.webm`);
48
+ }
49
+ function getBaseNameFromConfig(configPath) {
50
+ const base = basename(configPath, extname(configPath));
51
+ // Remove .demo or .config suffix if present
52
+ return base.replace(/\.(demo|config)$/, '');
53
+ }
54
+ export async function loadConfig(configPath, cliOutputDir) {
55
+ if (!await fileExists(configPath)) {
56
+ throw new Error(`Config file not found: ${configPath}`);
57
+ }
58
+ const config = await loadConfigFile(configPath);
59
+ const outputPath = resolveOutputPath(config, configPath, cliOutputDir);
60
+ return {
61
+ config,
62
+ configPath,
63
+ outputPath,
64
+ };
65
+ }
66
+ export async function findConfig(cwd = process.cwd()) {
67
+ const candidates = [
68
+ 'demo-reel.config.ts',
69
+ 'demo-reel.config.js',
70
+ 'demo-reel.config.mjs',
71
+ 'demo-reel.config.json',
72
+ ];
73
+ for (const candidate of candidates) {
74
+ const fullPath = join(cwd, candidate);
75
+ if (await fileExists(fullPath)) {
76
+ return fullPath;
77
+ }
78
+ }
79
+ return null;
80
+ }
81
+ export async function findScenarioFiles(cwd = process.cwd(), pattern = '**/*.demo.ts') {
82
+ const { glob } = await import('glob');
83
+ const files = await glob(pattern, {
84
+ cwd,
85
+ absolute: true,
86
+ ignore: ['node_modules/**', 'dist/**', 'test-results/**'],
87
+ });
88
+ return files.sort();
89
+ }
90
+ export async function loadScenario(name, cwd = process.cwd()) {
91
+ const candidates = [
92
+ `${name}.demo.ts`,
93
+ `${name}.demo.js`,
94
+ `${name}.demo.mjs`,
95
+ `${name}.config.ts`,
96
+ `${name}.config.js`,
97
+ `${name}.config.mjs`,
98
+ ];
99
+ for (const candidate of candidates) {
100
+ const fullPath = join(cwd, candidate);
101
+ if (await fileExists(fullPath)) {
102
+ return fullPath;
103
+ }
104
+ }
105
+ return null;
106
+ }
107
+ //# sourceMappingURL=config-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { demoReelConfigSchema, type DemoReelConfig } from './schemas.js';
2
+ export declare function defineConfig(config: DemoReelConfig): DemoReelConfig;
3
+ export declare function validateConfig(config: unknown): DemoReelConfig;
4
+ export { demoReelConfigSchema };
5
+ export type { DemoReelConfig } from './schemas.js';
6
+ export type * from './types.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAEzE,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAEnE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,cAAc,CAE9D;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAChC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,mBAAmB,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ import { demoReelConfigSchema } from './schemas.js';
2
+ export function defineConfig(config) {
3
+ return config;
4
+ }
5
+ export function validateConfig(config) {
6
+ return demoReelConfigSchema.parse(config);
7
+ }
8
+ export { demoReelConfigSchema };
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAuB,MAAM,cAAc,CAAC;AAEzE,MAAM,UAAU,YAAY,CAAC,MAAsB;IACjD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAe;IAC5C,OAAO,oBAAoB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC5C,CAAC;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Page } from 'playwright';
2
+ import type { DemoReelConfig } from './schemas.js';
3
+ export declare const runDemo: (page: Page, config: DemoReelConfig) => Promise<void>;
4
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,IAAI,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAEV,cAAc,EAMf,MAAM,cAAc,CAAC;AAooBtB,eAAO,MAAM,OAAO,GAAU,MAAM,IAAI,EAAE,QAAQ,cAAc,kBAsB/D,CAAC"}