@jskit-ai/create-app 0.1.133 → 0.1.134

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/create-app",
3
- "version": "0.1.133",
3
+ "version": "0.1.134",
4
4
  "description": "Scaffold JSKIT app shells.",
5
5
  "type": "module",
6
6
  "files": [
@@ -20,7 +20,7 @@
20
20
  "./client": "./src/client/index.js"
21
21
  },
22
22
  "dependencies": {
23
- "@jskit-ai/jskit-cli": "0.2.136"
23
+ "@jskit-ai/jskit-cli": "0.2.137"
24
24
  },
25
25
  "engines": {
26
26
  "node": "^22.12.0 || ^24.0.0 || ^26.0.0"
@@ -16,7 +16,6 @@ const DEFAULT_INITIAL_BUNDLES = "none";
16
16
  const DEFAULT_PLAYWRIGHT_VERSION = "1.61.1";
17
17
  const INITIAL_BUNDLE_PRESETS = new Set(["none", "auth"]);
18
18
  const TENANCY_MODES = new Set(["none", "personal", "workspaces"]);
19
- const EXACT_SEMVER_PATTERN = /^\d+\.\d+\.\d+$/u;
20
19
  const ALLOWED_EXISTING_TARGET_ENTRIES = new Set([".git"]);
21
20
  const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
22
21
  const TEMPLATES_ROOT = path.join(PACKAGE_ROOT, "templates");
@@ -57,12 +56,12 @@ function normalizeTenancyMode(value, { showUsage = true } = {}) {
57
56
 
58
57
  function normalizePlaywrightVersion(value, { showUsage = true } = {}) {
59
58
  const normalized = String(value || "").trim();
60
- if (EXACT_SEMVER_PATTERN.test(normalized)) {
59
+ if (normalized === DEFAULT_PLAYWRIGHT_VERSION) {
61
60
  return normalized;
62
61
  }
63
62
 
64
63
  throw createCliError(
65
- `Invalid --playwright-version value "${value}". Expected an exact x.y.z version.`,
64
+ `Invalid --playwright-version value "${value}". JSKIT requires ${DEFAULT_PLAYWRIGHT_VERSION}.`,
66
65
  { showUsage }
67
66
  );
68
67
  }
@@ -262,7 +261,7 @@ function printUsage(stream = process.stderr) {
262
261
  stream.write(" --title <text> App title used for template replacements\n");
263
262
  stream.write(" --target <path> Target directory (default: ./<app-name>)\n");
264
263
  stream.write(" --initial-bundles <preset> Optional initial setup preset: none | auth (default: none)\n");
265
- stream.write(` --playwright-version <x.y.z> Exact Playwright test version (default: ${DEFAULT_PLAYWRIGHT_VERSION})\n`);
264
+ stream.write(` --playwright-version <version> Supported Playwright test version (${DEFAULT_PLAYWRIGHT_VERSION})\n`);
266
265
  stream.write(" --tenancy-mode <mode> Optional config seed: none | personal | workspaces\n");
267
266
  stream.write(" --force Allow writing into a non-empty target directory\n");
268
267
  stream.write(" --dry-run Print planned writes without changing the filesystem\n");
@@ -48,7 +48,13 @@
48
48
  "value": "0.x"
49
49
  }
50
50
  },
51
- "devDependencies": {},
51
+ "devDependencies": {
52
+ "@playwright/test": {
53
+ "hadPrevious": true,
54
+ "previousValue": "__PLAYWRIGHT_VERSION__",
55
+ "value": "__PLAYWRIGHT_VERSION__"
56
+ }
57
+ },
52
58
  "scripts": {}
53
59
  },
54
60
  "text": {
@@ -0,0 +1,4 @@
1
+ import { defineConfig } from "@playwright/test";
2
+ import { createJskitPlaywrightConfig } from "@jskit-ai/jskit-cli/test/playwright";
3
+
4
+ export default defineConfig(createJskitPlaywrightConfig());
@@ -1,57 +1,4 @@
1
1
  import { expect, test } from "@playwright/test";
2
+ import { runGeneratedAppSmoke } from "@jskit-ai/jskit-cli/test/playwright";
2
3
 
3
- const BASE_URL = String(process.env.PLAYWRIGHT_BASE_URL || "http://127.0.0.1:5173").replace(/\/+$/u, "");
4
- const SMOKE_PATH = String(process.env.JSKIT_PLAYWRIGHT_SMOKE_PATH || "/home");
5
-
6
- const viewports = [
7
- { name: "compact", width: 390, height: 844 },
8
- { name: "medium", width: 768, height: 1024 },
9
- { name: "expanded", width: 1280, height: 900 }
10
- ];
11
-
12
- async function expectNoHorizontalOverflow(page) {
13
- const metrics = await page.evaluate(() => ({
14
- clientWidth: document.documentElement.clientWidth,
15
- scrollWidth: document.documentElement.scrollWidth
16
- }));
17
-
18
- expect(metrics.scrollWidth).toBeLessThanOrEqual(metrics.clientWidth + 1);
19
- }
20
-
21
- async function expectGeneratedScreenContract(page) {
22
- const screen = page.locator(".generated-ui-screen").first();
23
-
24
- await expect(screen).toBeVisible();
25
- await expect(screen).toHaveClass(/generated-ui-screen--app/u);
26
- await expect(screen.locator("h1").first()).toBeVisible();
27
- }
28
-
29
- async function expectVisibleTapTargets(page) {
30
- const targetHeights = await page.locator("a[href], button, [role='button'], .v-btn, .v-list-item").evaluateAll(
31
- (elements) => elements
32
- .filter((element) => {
33
- const rect = element.getBoundingClientRect();
34
- const style = window.getComputedStyle(element);
35
- return style.display !== "none" && style.visibility !== "hidden" && rect.width > 0 && rect.height > 0;
36
- })
37
- .map((element) => element.getBoundingClientRect().height)
38
- );
39
-
40
- for (const height of targetHeights) {
41
- expect(height).toBeGreaterThanOrEqual(48);
42
- }
43
- }
44
-
45
- test.describe("generated base app responsive smoke", () => {
46
- for (const viewport of viewports) {
47
- test(`${viewport.name} home route renders without horizontal overflow`, async ({ page }) => {
48
- await page.setViewportSize({ width: viewport.width, height: viewport.height });
49
- await page.goto(`${BASE_URL}${SMOKE_PATH}`);
50
- await expect(page.locator("body")).toBeVisible();
51
- await expect(page.getByText("Ready")).toBeVisible();
52
- await expectGeneratedScreenContract(page);
53
- await expectVisibleTapTargets(page);
54
- await expectNoHorizontalOverflow(page);
55
- });
56
- }
57
- });
4
+ runGeneratedAppSmoke({ test, expect, expectedText: "Ready" });
@@ -0,0 +1,4 @@
1
+ import { defineConfig } from "@playwright/test";
2
+ import { createJskitPlaywrightConfig } from "@jskit-ai/jskit-cli/test/playwright";
3
+
4
+ export default defineConfig(createJskitPlaywrightConfig());
@@ -1,57 +1,4 @@
1
1
  import { expect, test } from "@playwright/test";
2
+ import { runGeneratedAppSmoke } from "@jskit-ai/jskit-cli/test/playwright";
2
3
 
3
- const BASE_URL = String(process.env.PLAYWRIGHT_BASE_URL || "http://127.0.0.1:5173").replace(/\/+$/u, "");
4
- const SMOKE_PATH = String(process.env.JSKIT_PLAYWRIGHT_SMOKE_PATH || "/home");
5
-
6
- const viewports = [
7
- { name: "compact", width: 390, height: 844 },
8
- { name: "medium", width: 768, height: 1024 },
9
- { name: "expanded", width: 1280, height: 900 }
10
- ];
11
-
12
- async function expectNoHorizontalOverflow(page) {
13
- const metrics = await page.evaluate(() => ({
14
- clientWidth: document.documentElement.clientWidth,
15
- scrollWidth: document.documentElement.scrollWidth
16
- }));
17
-
18
- expect(metrics.scrollWidth).toBeLessThanOrEqual(metrics.clientWidth + 1);
19
- }
20
-
21
- async function expectGeneratedScreenContract(page) {
22
- const screen = page.locator(".generated-ui-screen").first();
23
-
24
- await expect(screen).toBeVisible();
25
- await expect(screen).toHaveClass(/generated-ui-screen--app/u);
26
- await expect(screen.locator("h1").first()).toBeVisible();
27
- }
28
-
29
- async function expectVisibleTapTargets(page) {
30
- const targetHeights = await page.locator("a[href], button, [role='button'], .v-btn, .v-list-item").evaluateAll(
31
- (elements) => elements
32
- .filter((element) => {
33
- const rect = element.getBoundingClientRect();
34
- const style = window.getComputedStyle(element);
35
- return style.display !== "none" && style.visibility !== "hidden" && rect.width > 0 && rect.height > 0;
36
- })
37
- .map((element) => element.getBoundingClientRect().height)
38
- );
39
-
40
- for (const height of targetHeights) {
41
- expect(height).toBeGreaterThanOrEqual(48);
42
- }
43
- }
44
-
45
- test.describe("generated base app responsive smoke", () => {
46
- for (const viewport of viewports) {
47
- test(`${viewport.name} home route renders without horizontal overflow`, async ({ page }) => {
48
- await page.setViewportSize({ width: viewport.width, height: viewport.height });
49
- await page.goto(`${BASE_URL}${SMOKE_PATH}`);
50
- await expect(page.locator("body")).toBeVisible();
51
- await expect(page.getByText("Home base")).toBeVisible();
52
- await expectGeneratedScreenContract(page);
53
- await expectVisibleTapTargets(page);
54
- await expectNoHorizontalOverflow(page);
55
- });
56
- }
57
- });
4
+ runGeneratedAppSmoke({ test, expect, expectedText: "Home base" });