@sealcode/sealgen 0.8.53 → 0.9.1

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/lib/add-route.js CHANGED
@@ -31,7 +31,7 @@ async function addRoute(params, app_directory = process.cwd()) {
31
31
  {
32
32
  type: "text",
33
33
  name: "url",
34
- message: "Enter a full absolute path for the new route (e.g. /admin/users/add): ",
34
+ message: "Enter a full absolute path for the new route (for example: /admin/users/:id/edit): ",
35
35
  validate: (s) => s.trim()[0] == "/" ? true : "Should start with a '/'",
36
36
  },
37
37
  {
package/lib/build.js CHANGED
@@ -28,6 +28,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.buildProject = void 0;
30
30
  const esbuild_1 = require("esbuild");
31
+ const fs_1 = require("fs");
31
32
  const esbuild_sass_plugin_1 = require("esbuild-sass-plugin");
32
33
  const chokidar = __importStar(require("chokidar"));
33
34
  const tiny_glob_1 = __importDefault(require("tiny-glob"));
@@ -35,6 +36,14 @@ const find_scss_includes_1 = require("./find-scss-includes");
35
36
  const sleep_1 = require("./utils/sleep");
36
37
  const generate_collections_1 = require("./generate-collections");
37
38
  const generate_routes_1 = require("./generate-routes");
39
+ const generate_names = (function* generate_names() {
40
+ let base_name = "______unique_import_";
41
+ let count = 0;
42
+ while (true) {
43
+ yield base_name + count;
44
+ count++;
45
+ }
46
+ })();
38
47
  async function build_ts() {
39
48
  await Promise.all([(0, generate_collections_1.generateCollections)(), (0, generate_routes_1.generateRoutes)()]);
40
49
  const entryPoints = (await (0, tiny_glob_1.default)("./src/back/**/*.ts")).filter((path) => !path.includes(".#"));
@@ -46,7 +55,27 @@ async function build_ts() {
46
55
  logLevel: "info",
47
56
  platform: "node",
48
57
  target: "es2022",
49
- format: "cjs",
58
+ format: "esm",
59
+ plugins: [
60
+ {
61
+ name: "remove-named-imports",
62
+ setup(build) {
63
+ build.onLoad({ filter: /.*/ }, async ({ path }) => {
64
+ const named_and_default_regex = /^import\s+((\S+),\s+)?({\s*[^}]+})\s+from\s+("[^"]+");\s*$/gm;
65
+ const old_content = await fs_1.promises.readFile(path, "utf-8");
66
+ const contents = old_content.replace(named_and_default_regex, (entire_string, default_import_name, _, all_named, module_path) => {
67
+ const new_name = generate_names.next().value;
68
+ return `import * as ${new_name} from ${module_path}; ${default_import_name
69
+ ? `const ${default_import_name.replace(",", "")} = ${new_name}`
70
+ : ""}; const ${all_named.replaceAll(/\s+as\s+/g, ": ")} = ${/\s+default\s+as/.test(all_named)
71
+ ? `${new_name};`
72
+ : `${new_name}.default || ${new_name};`}`;
73
+ });
74
+ return { contents, loader: "ts" };
75
+ });
76
+ },
77
+ },
78
+ ],
50
79
  });
51
80
  }
52
81
  catch (e) {
@@ -61,7 +61,7 @@ async function generateCollections() {
61
61
  import { App } from "sealious";
62
62
 
63
63
  ${file_data
64
- .map(({ class_name, urlname }) => `import _${class_name} from "./${urlname}";`)
64
+ .map(({ class_name, urlname }) => `import _${class_name} from "./${urlname}.js";`)
65
65
  .join("\n")}
66
66
 
67
67
  ${file_data
@@ -84,7 +84,7 @@ async function generateRoutes() {
84
84
 
85
85
  import Router from "@koa/router";
86
86
  import { mount } from "@sealcode/sealgen";
87
- import * as URLs from "./urls"
87
+ import * as URLs from "./urls.js"
88
88
 
89
89
  ${files
90
90
  .map(({ actionName, fullpath }) => `import { default as ${actionName} } from "${(0, import_path_1.importPath)(target_locreq.resolve("src/back/routes/routes.ts"), fullpath)}";`)
package/lib/page/list.js CHANGED
@@ -77,31 +77,38 @@ ${this.renderListContainer(ctx, this.renderItems(ctx, values))}`;
77
77
  async renderPagination(ctx, values) {
78
78
  const { itemsPerPage, page } = await this.getPaginationConfig(ctx);
79
79
  const totalIems = await this.getTotalPages(ctx, itemsPerPage, values);
80
- return (0, tempstream_1.tempstream /* HTML */) `<center>
81
- ${page > 1 ? this.renderPageButton(ctx, 1, "Pierwsza strona") : ""}
82
- ${page > 1
80
+ return (0, tempstream_1.tempstream /* HTML */) `<div class="list-pagination">
81
+ <div class="list-pagination__left">
82
+ ${page > 1
83
+ ? this.renderPageButton(ctx, 1, "Pierwsza strona")
84
+ : ""}
85
+ ${page > 1
83
86
  ? this.renderPageButton(ctx, page - 1, "Poprzednia strona")
84
87
  : ""}
85
-
86
- <select onchange="if (this.value) Turbo.visit(this.value)">
87
- ${Array.from((0, utils_1.naturalNumbers)(1, totalIems)).map((n) => /* HTML */ `<option
88
- value="${(0, utils_1.UrlWithNewParams)(ctx,
88
+ </div>
89
+ <div class="list-pagination__center">
90
+ <select onchange="if (this.value) Turbo.visit(this.value)">
91
+ ${Array.from((0, utils_1.naturalNumbers)(1, totalIems)).map((n) => /* HTML */ `<option
92
+ value="${(0, utils_1.UrlWithNewParams)(ctx,
89
93
  //eslint-disable-next-line @typescript-eslint/consistent-type-assertions
90
94
  this.propsParser.overwriteProp(ctx, {
91
95
  page: n,
92
96
  }))}"
93
- ${page === n ? "selected" : ""}
94
- >
95
- ${n}
96
- </option>`)}
97
- </select>
98
- ${page < totalIems
97
+ ${page === n ? "selected" : ""}
98
+ >
99
+ ${n}
100
+ </option>`)}
101
+ </select>
102
+ </div>
103
+ <div class="list-pagination__right">
104
+ ${page < totalIems
99
105
  ? this.renderPageButton(ctx, page + 1, "Następna strona")
100
106
  : ""}
101
- ${page < totalIems
107
+ ${page < totalIems
102
108
  ? this.renderPageButton(ctx, totalIems, "Ostatnia strona")
103
109
  : ""}
104
- </center>`;
110
+ </div>
111
+ </div>`;
105
112
  }
106
113
  renderPageButton(ctx, page, text) {
107
114
  return /* HTML */ `<a
@@ -6,8 +6,8 @@ async function formTemplate(action_name, newfilefullpath) {
6
6
  const rel = (0, import_path_1.curryImportPath)(newfilefullpath);
7
7
  return `import { Context } from "koa";
8
8
  import { Form, FormData, FormDataValue, Fields, Controls } from "@sealcode/sealgen";
9
- import html from "${rel("src/back/html")}";
10
- import { Users } from "${rel("src/back/collections/collections")}";
9
+ import html from "${rel("src/back/html.js")}";
10
+ import { Users } from "${rel("src/back/collections/collections.js")}";
11
11
 
12
12
  export const actionName = "${action_name}";
13
13
 
@@ -20,8 +20,8 @@ const listTemplate = async (action_name, newfilefullpath) => {
20
20
  return `import { Context } from "koa";
21
21
  import { CollectionItem } from "sealious";
22
22
  import { tempstream } from "tempstream";
23
- import { ${uppercase_collection} } from "${rel("src/back/collections/collections")}";
24
- import html from "${rel("src/back/html.ts")}";
23
+ import { ${uppercase_collection} } from "${rel("src/back/collections/collections.js")}";
24
+ import html from "${rel("src/back/html.js")}";
25
25
  import { SealiousItemListPage, BaseListPageFields } from "@sealcode/sealgen";
26
26
 
27
27
  export const actionName = "${action_name}";
@@ -43,7 +43,7 @@ export default new (class ${action_name}Page extends SealiousItemListPage<
43
43
  "${uppercase_collection}",
44
44
  tempstream/* HTML */ \`<div>
45
45
  <h2>${uppercase_collection} List</h2>
46
- <table>
46
+ <table class="sealious-list">
47
47
  \${this.renderTableHead(ctx, [
48
48
  { field: "id" },
49
49
  ...Object.keys(Patrons.fields).map((field) => ({
@@ -5,7 +5,7 @@ const utils_1 = require("../utils/utils");
5
5
  async function multiformTemplate(action_name, newfilefullpath) {
6
6
  const rel = (0, utils_1.curryImportPath)(newfilefullpath);
7
7
  return `import { Context } from "koa";
8
- import html from "${rel("src/back/html")}";
8
+ import html from "${rel("src/back/html.js")}";
9
9
  import { Controls, Fields, Form, FormMessage, Multiform } from "@sealcode/sealgen";
10
10
  import { FlatTemplatable } from "tempstream";
11
11
 
@@ -7,7 +7,7 @@ async function pageTemplate(action_name, newfilefullpath) {
7
7
  return `import { Context } from "koa";
8
8
  import { tempstream } from "tempstream";
9
9
  import { Page } from "@sealcode/sealgen";
10
- import html from "${rel("src/back/html")}";
10
+ import html from "${rel("src/back/html.js")}";
11
11
 
12
12
  export const actionName = "${action_name}";
13
13
 
@@ -4,22 +4,52 @@ exports.testTemplate = void 0;
4
4
  const import_path_1 = require("../utils/import-path");
5
5
  function testTemplate(action_name, new_file_fullpath) {
6
6
  const rel = (0, import_path_1.curryImportPath)(new_file_fullpath);
7
- return `import { withProdApp } from "${rel("src/back/test_utils/with-prod-app")}";
8
- import { LONG_TEST_TIMEOUT, webhintURL } from "${rel("src/back/test_utils/webhint")}";
9
- import { ${action_name}URL } from "${rel("src/back/routes/urls")}";
7
+ return `import { withProdApp } from "${rel("src/back/test_utils/with-prod-app.js")}";
8
+ import { LONG_TEST_TIMEOUT, webhintURL } from "${rel("src/back/test_utils/webhint.js")}";
9
+ import { ${action_name}URL } from "${rel("src/back/routes/urls.js")}";
10
+ import { getBrowser } from "${rel("src/test_utils/browser-creator.js")}";
11
+
12
+ describe("${action_name} webhint", () => {
13
+ it(
14
+ "doesn't crash",
15
+ async function () {
16
+ return withProdApp(async ({ base_url, rest_api }) => {
17
+ await rest_api.get(${action_name}URL);
18
+ await webhintURL(base_url + ${action_name}URL);
19
+ // alternatively you can use webhintHTML for faster but less precise scans
20
+ // or for scanning responses of requests that use some form of authorization:
21
+ // const response = await rest_api.get(${action_name}URL);
22
+ // await webhintHTML(response);
23
+ });
24
+ },
25
+ VERY_LONG_TEST_TIMEOUT
26
+ );
27
+ });
10
28
 
11
29
  describe("${action_name}", () => {
12
- it("doesn't crash", async function () {
13
- this.timeout(LONG_TEST_TIMEOUT);
14
- return withProdApp(async ({ base_url, rest_api }) => {
15
- await rest_api.get(${action_name}URL);
16
- await webhintURL(base_url + ${action_name}URL);
17
- // alternatively you can use webhintHTML for faster but less precise scans
18
- // or for scanning responses of requests that use some form of authorization:
19
- // const response = await rest_api.get(${action_name}URL);
20
- // await webhintHTML(response);
21
- });
30
+ let page: Page;
31
+ let browser: Browser;
32
+ let context: BrowserContext;
33
+
34
+ beforeEach(async () => {
35
+ browser = await getBrowser();
36
+ context = await browser.newContext();
37
+ page = await context.newPage();
22
38
  });
39
+
40
+ afterEach(async () => {
41
+ await context.close();
42
+ });
43
+
44
+ it(
45
+ "works as expected",
46
+ async function () {
47
+ return withProdApp(async ({ base_url }) => {
48
+ await page.goto(base_url + ${action_name}URL);
49
+ });
50
+ },
51
+ VERY_LONG_TEST_TIMEOUT
52
+ );
23
53
  });
24
54
  `;
25
55
  }
@@ -7,7 +7,7 @@ async function statefulPageTemplate(action_name, newfilefullpath) {
7
7
  return `import { BaseContext } from "koa";
8
8
  import { tempstream, Templatable } from "tempstream";
9
9
  import { StatefulPage } from "@sealcode/sealgen";
10
- import html from "${rel("src/back/html")}";
10
+ import html from "${rel("src/back/html.js")}";
11
11
 
12
12
  export const actionName = "${action_name}";
13
13
 
@@ -8,7 +8,7 @@ const path_1 = require("path");
8
8
  const locreq_1 = __importDefault(require("locreq"));
9
9
  const target_locreq = (0, locreq_1.default)(process.cwd());
10
10
  function importPath(project_module_path, project_target_path) {
11
- let result = (0, path_1.relative)((0, path_1.dirname)(target_locreq.resolve(project_module_path)), target_locreq.resolve(project_target_path).replace(/.ts$/, ""));
11
+ let result = (0, path_1.relative)((0, path_1.dirname)(target_locreq.resolve(project_module_path)), target_locreq.resolve(project_target_path).replace(/.ts$/, ".js"));
12
12
  if (result[0] != ".") {
13
13
  result = "./" + result;
14
14
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sealcode/sealgen",
3
- "version": "0.8.53",
3
+ "version": "0.9.1",
4
4
  "description": "Module to automate adding routes and collections to a sealious application",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -40,7 +40,7 @@
40
40
  "playwright": "^1.29.2",
41
41
  "source-map-support": "^0.5.21",
42
42
  "ts-node": "^10.9.1",
43
- "typescript": "^4.4",
43
+ "typescript": "^4.7",
44
44
  "wait-port": "^1.0.4"
45
45
  },
46
46
  "types": "./@types/index.d.ts",
package/src/add-route.ts CHANGED
@@ -31,7 +31,7 @@ export async function addRoute(
31
31
  type: "text",
32
32
  name: "url",
33
33
  message:
34
- "Enter a full absolute path for the new route (e.g. /admin/users/add): ",
34
+ "Enter a full absolute path for the new route (for example: /admin/users/:id/edit): ",
35
35
  validate: (s: string) =>
36
36
  s.trim()[0] == "/" ? true : "Should start with a '/'",
37
37
  },
package/src/build.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { build, BuildResult } from "esbuild";
2
+ import { promises as fs } from "fs";
2
3
  import { sassPlugin } from "esbuild-sass-plugin";
3
4
  import * as chokidar from "chokidar";
4
5
  import { default as glob } from "tiny-glob";
@@ -7,6 +8,15 @@ import { sleep } from "./utils/sleep";
7
8
  import { generateCollections } from "./generate-collections";
8
9
  import { generateRoutes } from "./generate-routes";
9
10
 
11
+ const generate_names = (function* generate_names() {
12
+ let base_name = "______unique_import_";
13
+ let count = 0;
14
+ while (true) {
15
+ yield base_name + count;
16
+ count++;
17
+ }
18
+ })();
19
+
10
20
  async function build_ts() {
11
21
  await Promise.all([generateCollections(), generateRoutes()]);
12
22
  const entryPoints = (await glob("./src/back/**/*.ts")).filter(
@@ -20,7 +30,52 @@ async function build_ts() {
20
30
  logLevel: "info",
21
31
  platform: "node",
22
32
  target: "es2022",
23
- format: "cjs",
33
+ format: "esm",
34
+ plugins: [
35
+ {
36
+ name: "remove-named-imports", // named imports sometime cause some esm incompatibilities, like the "is a CommonJS module, which may not support all module.exports as named exports." error
37
+ setup(build) {
38
+ build.onLoad({ filter: /.*/ }, async ({ path }) => {
39
+ const named_and_default_regex =
40
+ /^import\s+((\S+),\s+)?({\s*[^}]+})\s+from\s+("[^"]+");\s*$/gm;
41
+
42
+ const old_content = await fs.readFile(
43
+ path,
44
+ "utf-8"
45
+ );
46
+ const contents = old_content.replace(
47
+ named_and_default_regex,
48
+ (
49
+ entire_string,
50
+ default_import_name,
51
+ _,
52
+ all_named,
53
+ module_path
54
+ ) => {
55
+ const new_name =
56
+ generate_names.next().value;
57
+ return `import * as ${new_name} from ${module_path}; ${
58
+ default_import_name
59
+ ? `const ${default_import_name.replace(
60
+ ",",
61
+ ""
62
+ )} = ${new_name}`
63
+ : ""
64
+ }; const ${all_named.replaceAll(
65
+ /\s+as\s+/g,
66
+ ": "
67
+ )} = ${
68
+ /\s+default\s+as/.test(all_named)
69
+ ? `${new_name};`
70
+ : `${new_name}.default || ${new_name};`
71
+ }`;
72
+ }
73
+ );
74
+ return { contents, loader: "ts" };
75
+ });
76
+ },
77
+ },
78
+ ],
24
79
  });
25
80
  } catch (e) {
26
81
  console.error(e.message);
@@ -51,7 +51,7 @@ import { App } from "sealious";
51
51
  ${file_data
52
52
  .map(
53
53
  ({ class_name, urlname }) =>
54
- `import _${class_name} from "./${urlname}";`
54
+ `import _${class_name} from "./${urlname}.js";`
55
55
  )
56
56
  .join("\n")}
57
57
 
@@ -77,7 +77,7 @@ export async function generateRoutes(): Promise<void> {
77
77
 
78
78
  import Router from "@koa/router";
79
79
  import { mount } from "@sealcode/sealgen";
80
- import * as URLs from "./urls"
80
+ import * as URLs from "./urls.js"
81
81
 
82
82
  ${files
83
83
  .map(
package/src/page/list.ts CHANGED
@@ -120,35 +120,42 @@ ${this.renderListContainer(ctx, this.renderItems(ctx, values))}`;
120
120
  const { itemsPerPage, page } = await this.getPaginationConfig(ctx);
121
121
  const totalIems = await this.getTotalPages(ctx, itemsPerPage, values);
122
122
 
123
- return tempstream/* HTML */ `<center>
124
- ${page > 1 ? this.renderPageButton(ctx, 1, "Pierwsza strona") : ""}
125
- ${page > 1
126
- ? this.renderPageButton(ctx, page - 1, "Poprzednia strona")
127
- : ""}
128
-
129
- <select onchange="if (this.value) Turbo.visit(this.value)">
130
- ${Array.from(naturalNumbers(1, totalIems)).map(
131
- (n) => /* HTML */ `<option
132
- value="${UrlWithNewParams(
133
- ctx,
134
- //eslint-disable-next-line @typescript-eslint/consistent-type-assertions
135
- this.propsParser.overwriteProp(ctx, {
136
- page: n,
137
- } as Partial<Record<string, unknown>>)
138
- )}"
139
- ${page === n ? "selected" : ""}
140
- >
141
- ${n}
142
- </option>`
143
- )}
144
- </select>
145
- ${page < totalIems
146
- ? this.renderPageButton(ctx, page + 1, "Następna strona")
147
- : ""}
148
- ${page < totalIems
149
- ? this.renderPageButton(ctx, totalIems, "Ostatnia strona")
150
- : ""}
151
- </center>`;
123
+ return tempstream/* HTML */ `<div class="list-pagination">
124
+ <div class="list-pagination__left">
125
+ ${page > 1
126
+ ? this.renderPageButton(ctx, 1, "Pierwsza strona")
127
+ : ""}
128
+ ${page > 1
129
+ ? this.renderPageButton(ctx, page - 1, "Poprzednia strona")
130
+ : ""}
131
+ </div>
132
+ <div class="list-pagination__center">
133
+ <select onchange="if (this.value) Turbo.visit(this.value)">
134
+ ${Array.from(naturalNumbers(1, totalIems)).map(
135
+ (n) => /* HTML */ `<option
136
+ value="${UrlWithNewParams(
137
+ ctx,
138
+ //eslint-disable-next-line @typescript-eslint/consistent-type-assertions
139
+ this.propsParser.overwriteProp(ctx, {
140
+ page: n,
141
+ } as Partial<Record<string, unknown>>)
142
+ )}"
143
+ ${page === n ? "selected" : ""}
144
+ >
145
+ ${n}
146
+ </option>`
147
+ )}
148
+ </select>
149
+ </div>
150
+ <div class="list-pagination__right">
151
+ ${page < totalIems
152
+ ? this.renderPageButton(ctx, page + 1, "Następna strona")
153
+ : ""}
154
+ ${page < totalIems
155
+ ? this.renderPageButton(ctx, totalIems, "Ostatnia strona")
156
+ : ""}
157
+ </div>
158
+ </div>`;
152
159
  }
153
160
 
154
161
  private renderPageButton(ctx: Context, page: number, text: string) {
@@ -7,8 +7,8 @@ export async function formTemplate(
7
7
  const rel = curryImportPath(newfilefullpath);
8
8
  return `import { Context } from "koa";
9
9
  import { Form, FormData, FormDataValue, Fields, Controls } from "@sealcode/sealgen";
10
- import html from "${rel("src/back/html")}";
11
- import { Users } from "${rel("src/back/collections/collections")}";
10
+ import html from "${rel("src/back/html.js")}";
11
+ import { Users } from "${rel("src/back/collections/collections.js")}";
12
12
 
13
13
  export const actionName = "${action_name}";
14
14
 
@@ -25,9 +25,9 @@ export const listTemplate = async (
25
25
  import { CollectionItem } from "sealious";
26
26
  import { tempstream } from "tempstream";
27
27
  import { ${uppercase_collection} } from "${rel(
28
- "src/back/collections/collections"
28
+ "src/back/collections/collections.js"
29
29
  )}";
30
- import html from "${rel("src/back/html.ts")}";
30
+ import html from "${rel("src/back/html.js")}";
31
31
  import { SealiousItemListPage, BaseListPageFields } from "@sealcode/sealgen";
32
32
 
33
33
  export const actionName = "${action_name}";
@@ -49,7 +49,7 @@ export default new (class ${action_name}Page extends SealiousItemListPage<
49
49
  "${uppercase_collection}",
50
50
  tempstream/* HTML */ \`<div>
51
51
  <h2>${uppercase_collection} List</h2>
52
- <table>
52
+ <table class="sealious-list">
53
53
  \${this.renderTableHead(ctx, [
54
54
  { field: "id" },
55
55
  ...Object.keys(Patrons.fields).map((field) => ({
@@ -6,7 +6,7 @@ export async function multiformTemplate(
6
6
  ): Promise<string> {
7
7
  const rel = curryImportPath(newfilefullpath);
8
8
  return `import { Context } from "koa";
9
- import html from "${rel("src/back/html")}";
9
+ import html from "${rel("src/back/html.js")}";
10
10
  import { Controls, Fields, Form, FormMessage, Multiform } from "@sealcode/sealgen";
11
11
  import { FlatTemplatable } from "tempstream";
12
12
 
@@ -7,7 +7,7 @@ export async function pageTemplate(
7
7
  return `import { Context } from "koa";
8
8
  import { tempstream } from "tempstream";
9
9
  import { Page } from "@sealcode/sealgen";
10
- import html from "${rel("src/back/html")}";
10
+ import html from "${rel("src/back/html.js")}";
11
11
 
12
12
  export const actionName = "${action_name}";
13
13
 
@@ -3,25 +3,55 @@ import { curryImportPath } from "../utils/import-path";
3
3
  export function testTemplate(action_name: string, new_file_fullpath: string) {
4
4
  const rel = curryImportPath(new_file_fullpath);
5
5
  return `import { withProdApp } from "${rel(
6
- "src/back/test_utils/with-prod-app"
6
+ "src/back/test_utils/with-prod-app.js"
7
7
  )}";
8
8
  import { LONG_TEST_TIMEOUT, webhintURL } from "${rel(
9
- "src/back/test_utils/webhint"
9
+ "src/back/test_utils/webhint.js"
10
10
  )}";
11
- import { ${action_name}URL } from "${rel("src/back/routes/urls")}";
11
+ import { ${action_name}URL } from "${rel("src/back/routes/urls.js")}";
12
+ import { getBrowser } from "${rel("src/test_utils/browser-creator.js")}";
13
+
14
+ describe("${action_name} webhint", () => {
15
+ it(
16
+ "doesn't crash",
17
+ async function () {
18
+ return withProdApp(async ({ base_url, rest_api }) => {
19
+ await rest_api.get(${action_name}URL);
20
+ await webhintURL(base_url + ${action_name}URL);
21
+ // alternatively you can use webhintHTML for faster but less precise scans
22
+ // or for scanning responses of requests that use some form of authorization:
23
+ // const response = await rest_api.get(${action_name}URL);
24
+ // await webhintHTML(response);
25
+ });
26
+ },
27
+ VERY_LONG_TEST_TIMEOUT
28
+ );
29
+ });
12
30
 
13
31
  describe("${action_name}", () => {
14
- it("doesn't crash", async function () {
15
- this.timeout(LONG_TEST_TIMEOUT);
16
- return withProdApp(async ({ base_url, rest_api }) => {
17
- await rest_api.get(${action_name}URL);
18
- await webhintURL(base_url + ${action_name}URL);
19
- // alternatively you can use webhintHTML for faster but less precise scans
20
- // or for scanning responses of requests that use some form of authorization:
21
- // const response = await rest_api.get(${action_name}URL);
22
- // await webhintHTML(response);
23
- });
32
+ let page: Page;
33
+ let browser: Browser;
34
+ let context: BrowserContext;
35
+
36
+ beforeEach(async () => {
37
+ browser = await getBrowser();
38
+ context = await browser.newContext();
39
+ page = await context.newPage();
24
40
  });
41
+
42
+ afterEach(async () => {
43
+ await context.close();
44
+ });
45
+
46
+ it(
47
+ "works as expected",
48
+ async function () {
49
+ return withProdApp(async ({ base_url }) => {
50
+ await page.goto(base_url + ${action_name}URL);
51
+ });
52
+ },
53
+ VERY_LONG_TEST_TIMEOUT
54
+ );
25
55
  });
26
56
  `;
27
57
  }
@@ -8,7 +8,7 @@ export async function statefulPageTemplate(
8
8
  return `import { BaseContext } from "koa";
9
9
  import { tempstream, Templatable } from "tempstream";
10
10
  import { StatefulPage } from "@sealcode/sealgen";
11
- import html from "${rel("src/back/html")}";
11
+ import html from "${rel("src/back/html.js")}";
12
12
 
13
13
  export const actionName = "${action_name}";
14
14
 
@@ -8,7 +8,7 @@ export function importPath(
8
8
  ): string {
9
9
  let result = relative(
10
10
  dirname(target_locreq.resolve(project_module_path)),
11
- target_locreq.resolve(project_target_path).replace(/.ts$/, "")
11
+ target_locreq.resolve(project_target_path).replace(/.ts$/, ".js")
12
12
  );
13
13
  if (result[0] != ".") {
14
14
  result = "./" + result;