@jsenv/cli 0.0.3 → 0.0.6
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 +7 -0
- package/jsenv_cli.js +358 -0
- package/package.json +7 -5
- package/template-node-package/.eslintignore +2 -0
- package/template-node-package/.eslintrc.cjs +102 -0
- package/template-node-package/.jsenv/jsenv_tests_output.txt +8 -0
- package/template-node-package/.prettierrc.yml +2 -0
- package/template-node-package/package.json +23 -0
- package/template-node-package/scripts/test.mjs +25 -0
- package/template-node-package/src/main.js +8 -0
- package/template-node-package/src/message.js +11 -0
- package/template-node-package/tests/message.test.mjs +21 -0
- package/template-web/.eslintignore +3 -0
- package/template-web/.eslintrc.cjs +138 -0
- package/template-web/.prettierrc.yml +2 -0
- package/template-web/babel.config.cjs +3 -0
- package/template-web/package.json +33 -0
- package/template-web/scripts/build.mjs +21 -0
- package/template-web/scripts/build_serve.mjs +16 -0
- package/template-web/scripts/dev.mjs +15 -0
- package/template-web/scripts/test.mjs +29 -0
- package/template-web/src/app/animals.js +11 -0
- package/template-web/src/app/counter.js +11 -0
- package/template-web/src/index.html +27 -0
- package/template-web/src/jsenv_logo.svg +140 -0
- package/template-web/src/main.css +4 -0
- package/template-web/src/main.js +31 -0
- package/template-web/src/tests/animals.test.html +32 -0
- package/template-web/src/tests/app.test.mjs +26 -0
- package/template-web-components/.eslintignore +3 -0
- package/template-web-components/.eslintrc.cjs +138 -0
- package/template-web-components/.prettierrc.yml +2 -0
- package/template-web-components/babel.config.cjs +3 -0
- package/template-web-components/package.json +35 -0
- package/template-web-components/scripts/build.mjs +21 -0
- package/template-web-components/scripts/build_serve.mjs +16 -0
- package/template-web-components/scripts/dev.mjs +15 -0
- package/template-web-components/scripts/test.mjs +29 -0
- package/template-web-components/src/app/animals.js +11 -0
- package/template-web-components/src/app/app_custom_element.css +4 -0
- package/template-web-components/src/app/app_custom_element.js +31 -0
- package/template-web-components/src/app/counter.js +11 -0
- package/template-web-components/src/app/custom_elements_redefine.js +5 -0
- package/template-web-components/src/index.html +27 -0
- package/template-web-components/src/jsenv_logo.svg +140 -0
- package/template-web-components/src/main.js +11 -0
- package/template-web-components/src/tests/animals.test.html +32 -0
- package/template-web-components/src/tests/app.test.mjs +26 -0
- package/template-web-preact/.eslintignore +3 -0
- package/template-web-preact/.eslintrc.cjs +175 -0
- package/template-web-preact/.prettierrc.yml +2 -0
- package/template-web-preact/babel.config.cjs +11 -0
- package/template-web-preact/package.json +40 -0
- package/template-web-preact/scripts/build.mjs +23 -0
- package/template-web-preact/scripts/build_serve.mjs +16 -0
- package/template-web-preact/scripts/dev.mjs +21 -0
- package/template-web-preact/scripts/test.mjs +28 -0
- package/template-web-preact/src/app/animals.js +11 -0
- package/template-web-preact/src/app/app.css +42 -0
- package/template-web-preact/src/app/app.jsx +52 -0
- package/template-web-preact/src/app/counter.jsx +20 -0
- package/template-web-preact/src/index.html +28 -0
- package/template-web-preact/src/main.jsx +5 -0
- package/template-web-preact/src/preact_logo.svg +6 -0
- package/template-web-preact/src/tests/animals.test.html +32 -0
- package/template-web-preact/src/tests/app.test.mjs +26 -0
- package/template-web-react/.eslintignore +3 -0
- package/template-web-react/.eslintrc.cjs +175 -0
- package/template-web-react/.prettierrc.yml +2 -0
- package/template-web-react/babel.config.cjs +12 -0
- package/template-web-react/package.json +41 -0
- package/template-web-react/scripts/build.mjs +23 -0
- package/template-web-react/scripts/build_serve.mjs +16 -0
- package/template-web-react/scripts/dev.mjs +21 -0
- package/template-web-react/scripts/test.mjs +28 -0
- package/template-web-react/src/app/animals.js +11 -0
- package/template-web-react/src/app/app.css +42 -0
- package/template-web-react/src/app/app.jsx +55 -0
- package/template-web-react/src/app/counter.jsx +19 -0
- package/template-web-react/src/index.html +28 -0
- package/template-web-react/src/main.jsx +14 -0
- package/template-web-react/src/react_logo.svg +7 -0
- package/template-web-react/src/tests/animals.test.html +32 -0
- package/template-web-react/src/tests/app.test.mjs +26 -0
- package/src/command_build.mjs +0 -185
- package/src/command_dev.mjs +0 -38
- package/src/command_preview.mjs +0 -22
- package/src/command_test.mjs +0 -59
- package/src/jsenv_cli.mjs +0 -66
- package/src/package_installer.js +0 -122
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file uses "@jsenv/eslint-config" to configure ESLint
|
|
3
|
+
* https://github.com/jsenv/eslint-config#eslint-config----
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
composeEslintConfig,
|
|
8
|
+
eslintConfigBase,
|
|
9
|
+
eslintConfigForPrettier,
|
|
10
|
+
eslintConfigToPreferExplicitGlobals,
|
|
11
|
+
jsenvEslintRules,
|
|
12
|
+
jsenvEslintRulesForImport,
|
|
13
|
+
jsenvEslintRulesForReact,
|
|
14
|
+
} = require("@jsenv/eslint-config");
|
|
15
|
+
|
|
16
|
+
const eslintConfig = composeEslintConfig(
|
|
17
|
+
eslintConfigBase,
|
|
18
|
+
|
|
19
|
+
// By default files are meant to be executed in Node.js
|
|
20
|
+
// and we want to tell this to ESLint.
|
|
21
|
+
// As a result ESLint can consider `window` as undefined
|
|
22
|
+
// and `global` as an existing global variable.
|
|
23
|
+
{
|
|
24
|
+
env: {
|
|
25
|
+
node: true,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
// enable top level await
|
|
30
|
+
{
|
|
31
|
+
parserOptions: {
|
|
32
|
+
ecmaVersion: 2022,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
// use "@babel/eslint-parser" until import assertions is supported natively by ESLint
|
|
37
|
+
{
|
|
38
|
+
parser: "@babel/eslint-parser",
|
|
39
|
+
parserOptions: {
|
|
40
|
+
requireConfigFile: false,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
// Reuse jsenv eslint rules
|
|
45
|
+
{
|
|
46
|
+
rules: {
|
|
47
|
+
...jsenvEslintRules,
|
|
48
|
+
// Example of code changing the ESLint configuration to enable a rule:
|
|
49
|
+
// 'prefer-const': ['error']
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
// js import plugin
|
|
54
|
+
{
|
|
55
|
+
plugins: ["import"],
|
|
56
|
+
settings: {
|
|
57
|
+
"import/resolver": {
|
|
58
|
+
"@jsenv/eslint-import-resolver": {
|
|
59
|
+
rootDirectoryUrl: __dirname,
|
|
60
|
+
packageConditions: ["node", "import"],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
rules: jsenvEslintRulesForImport,
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
// HTML plugin
|
|
68
|
+
{
|
|
69
|
+
plugins: ["html"],
|
|
70
|
+
settings: {
|
|
71
|
+
extensions: [".html"],
|
|
72
|
+
settings: {
|
|
73
|
+
"html/javascript-mime-types": [
|
|
74
|
+
"text/javascript",
|
|
75
|
+
"module",
|
|
76
|
+
"text/jsx",
|
|
77
|
+
"module/jsx",
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
// react plugin
|
|
84
|
+
{
|
|
85
|
+
plugins: ["react"],
|
|
86
|
+
settings: {
|
|
87
|
+
react: {
|
|
88
|
+
version: "detect",
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
rules: {
|
|
92
|
+
...jsenvEslintRulesForReact,
|
|
93
|
+
"react/jsx-filename-extension": ["error", { extensions: [".jsx"] }],
|
|
94
|
+
"react/react-in-jsx-scope": ["off"],
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
// jsx
|
|
99
|
+
{
|
|
100
|
+
parser: "@babel/eslint-parser",
|
|
101
|
+
parserOptions: {
|
|
102
|
+
ecmaFeatures: {
|
|
103
|
+
jsx: true,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
settings: {
|
|
107
|
+
extensions: [".jsx"],
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
// Configure which files are written for the web
|
|
112
|
+
{
|
|
113
|
+
overrides: [
|
|
114
|
+
{
|
|
115
|
+
files: ["./src/**"],
|
|
116
|
+
env: {
|
|
117
|
+
browser: true,
|
|
118
|
+
node: false,
|
|
119
|
+
},
|
|
120
|
+
settings: {
|
|
121
|
+
"import/resolver": {
|
|
122
|
+
"@jsenv/eslint-import-resolver": {
|
|
123
|
+
rootDirectoryUrl: `${__dirname}/src/`,
|
|
124
|
+
packageConditions: ["browser", "import"],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
// package is "type": "module" so:
|
|
133
|
+
// 1. disable commonjs globals by default
|
|
134
|
+
// 2. Re-enable commonjs into *.cjs files
|
|
135
|
+
{
|
|
136
|
+
globals: {
|
|
137
|
+
__filename: "off",
|
|
138
|
+
__dirname: "off",
|
|
139
|
+
require: "off",
|
|
140
|
+
exports: "off",
|
|
141
|
+
},
|
|
142
|
+
overrides: [
|
|
143
|
+
{
|
|
144
|
+
files: ["**/*.cjs"],
|
|
145
|
+
env: {
|
|
146
|
+
commonjs: true,
|
|
147
|
+
},
|
|
148
|
+
// inside *.cjs files. restore commonJS "globals"
|
|
149
|
+
globals: {
|
|
150
|
+
__filename: true,
|
|
151
|
+
__dirname: true,
|
|
152
|
+
require: true,
|
|
153
|
+
exports: true,
|
|
154
|
+
},
|
|
155
|
+
// inside *.cjs files, use commonjs module resolution
|
|
156
|
+
settings: {
|
|
157
|
+
"import/resolver": {
|
|
158
|
+
"@jsenv/eslint-import-resolver": {
|
|
159
|
+
rootDirectoryUrl: __dirname,
|
|
160
|
+
packageConditions: ["node", "require"],
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
eslintConfigToPreferExplicitGlobals,
|
|
169
|
+
|
|
170
|
+
// We are using prettier, disable all eslint rules
|
|
171
|
+
// already handled by prettier.
|
|
172
|
+
eslintConfigForPrettier,
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
module.exports = eslintConfig;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "jsenv-template-web-preact",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "npm run dev -- --open",
|
|
8
|
+
"dev": "node ./scripts/dev.mjs",
|
|
9
|
+
"test": "node ./scripts/test.mjs",
|
|
10
|
+
"test:coverage": "npm run test -- --coverage",
|
|
11
|
+
"build": "node ./scripts/build.mjs",
|
|
12
|
+
"build:serve": "node ./scripts/build_serve.mjs --open",
|
|
13
|
+
"eslint": "npx eslint . --ext=.html,.js,.jsx,.mjs,.cjs",
|
|
14
|
+
"prettier": "prettier --write .",
|
|
15
|
+
"playwright:install": "npx playwright install-deps && npx playwright install"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"preact": "10.22.1"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@babel/eslint-parser": "7.24.8",
|
|
22
|
+
"@babel/plugin-syntax-import-assertions": "7.24.7",
|
|
23
|
+
"@babel/plugin-transform-react-jsx": "7.24.7",
|
|
24
|
+
"@jsenv/assert": "4.1.4",
|
|
25
|
+
"@jsenv/core": "39.2.1",
|
|
26
|
+
"@jsenv/plugin-preact": "1.6.2",
|
|
27
|
+
"@jsenv/plugin-bundling": "2.6.17",
|
|
28
|
+
"@jsenv/plugin-minification": "1.5.5",
|
|
29
|
+
"@jsenv/eslint-config": "16.5.2",
|
|
30
|
+
"@jsenv/eslint-import-resolver": "8.1.2",
|
|
31
|
+
"@jsenv/test": "3.3.11",
|
|
32
|
+
"eslint": "8.56.0",
|
|
33
|
+
"eslint-plugin-html": "8.1.1",
|
|
34
|
+
"eslint-plugin-import": "2.29.1",
|
|
35
|
+
"eslint-plugin-react": "7.34.4",
|
|
36
|
+
"open": "10.1.0",
|
|
37
|
+
"@playwright/browser-chromium": "1.45.2",
|
|
38
|
+
"prettier": "3.3.3"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Optimize source files and write them into "./dist/"
|
|
3
|
+
* Read more in https://github.com/jsenv/core/wiki
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { build } from "@jsenv/core";
|
|
7
|
+
import { jsenvPluginPreact } from "@jsenv/plugin-preact";
|
|
8
|
+
|
|
9
|
+
await build({
|
|
10
|
+
sourceDirectoryUrl: new URL("../src/", import.meta.url),
|
|
11
|
+
buildDirectoryUrl: new URL("../dist/", import.meta.url),
|
|
12
|
+
entryPoints: {
|
|
13
|
+
"./index.html": "index.html",
|
|
14
|
+
},
|
|
15
|
+
bundling: {
|
|
16
|
+
js_module: {
|
|
17
|
+
chunks: {
|
|
18
|
+
vendors: { "file:///**/node_modules/": true },
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
plugins: [jsenvPluginPreact()],
|
|
23
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Start a server serving files into dist/.
|
|
3
|
+
* Useful to test the files generated during the build
|
|
4
|
+
* Read more in https://github.com/jsenv/core/wiki
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import open from "open";
|
|
8
|
+
import { startBuildServer } from "@jsenv/core";
|
|
9
|
+
|
|
10
|
+
const buildServer = await startBuildServer({
|
|
11
|
+
buildDirectoryUrl: new URL("../dist/", import.meta.url),
|
|
12
|
+
port: 3501,
|
|
13
|
+
});
|
|
14
|
+
if (process.argv.includes("--open")) {
|
|
15
|
+
open(buildServer.origin);
|
|
16
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Start a development server for files inside src/
|
|
3
|
+
* Read more in https://github.com/jsenv/core/wiki
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import open from "open";
|
|
7
|
+
import { startDevServer } from "@jsenv/core";
|
|
8
|
+
import { jsenvPluginPreact } from "@jsenv/plugin-preact";
|
|
9
|
+
|
|
10
|
+
export const devServer = await startDevServer({
|
|
11
|
+
sourceDirectoryUrl: new URL("../src/", import.meta.url),
|
|
12
|
+
plugins: [
|
|
13
|
+
jsenvPluginPreact({
|
|
14
|
+
refreshInstrumentation: { "file://**/*.jsx": true },
|
|
15
|
+
}),
|
|
16
|
+
],
|
|
17
|
+
port: 3400,
|
|
18
|
+
});
|
|
19
|
+
if (process.argv.includes("--open")) {
|
|
20
|
+
open(`${devServer.origin}`);
|
|
21
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Execute all test files
|
|
3
|
+
* Read more in https://github.com/jsenv/core/wiki
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { executeTestPlan, chromium, nodeWorkerThread } from "@jsenv/test";
|
|
7
|
+
|
|
8
|
+
await executeTestPlan({
|
|
9
|
+
rootDirectoryUrl: new URL("../", import.meta.url),
|
|
10
|
+
testPlan: {
|
|
11
|
+
"./src/**/*.test.html": {
|
|
12
|
+
chromium: {
|
|
13
|
+
runtime: chromium(),
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
"./src/**/*.test.mjs": {
|
|
17
|
+
node: {
|
|
18
|
+
runtime: nodeWorkerThread(),
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
webServer: {
|
|
23
|
+
origin: "http://localhost:3400",
|
|
24
|
+
moduleUrl: new URL("./dev.mjs", import.meta.url),
|
|
25
|
+
},
|
|
26
|
+
coverage: process.argv.includes("--coverage"),
|
|
27
|
+
githubCheck: false,
|
|
28
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file exists to show code using the browser runtime to operate:
|
|
3
|
+
* code writes "countDogs" function on window
|
|
4
|
+
*
|
|
5
|
+
* As a result testing "countDogs" should be done in a browser.
|
|
6
|
+
* See "animals.test.html"
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
window.countDogs = (animals) => {
|
|
10
|
+
return animals.filter((animal) => animal === "dog").length;
|
|
11
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
.app {
|
|
2
|
+
text-align: center;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.app_logo {
|
|
6
|
+
height: 40vmin;
|
|
7
|
+
pointer-events: none;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
11
|
+
.app_logo {
|
|
12
|
+
animation: app_logo_spin infinite 20s linear;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.app_header {
|
|
17
|
+
background-color: #282c34;
|
|
18
|
+
min-height: 100vh;
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
align-items: center;
|
|
22
|
+
justify-content: center;
|
|
23
|
+
font-size: calc(10px + 2vmin);
|
|
24
|
+
color: white;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.app_link {
|
|
28
|
+
color: #61dafb;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@keyframes app_logo_spin {
|
|
32
|
+
from {
|
|
33
|
+
transform: rotate(0deg);
|
|
34
|
+
}
|
|
35
|
+
to {
|
|
36
|
+
transform: rotate(360deg);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
button {
|
|
41
|
+
font-size: calc(10px + 2vmin);
|
|
42
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { useLayoutEffect } from "preact/hooks";
|
|
2
|
+
|
|
3
|
+
import appStyleSheet from "./app.css" with { type: "css" };
|
|
4
|
+
import { Counter } from "./counter.jsx";
|
|
5
|
+
|
|
6
|
+
const preactLogoUrl = new URL("../preact_logo.svg", import.meta.url);
|
|
7
|
+
|
|
8
|
+
export const App = () => {
|
|
9
|
+
useLayoutEffect(() => {
|
|
10
|
+
document.adoptedStyleSheets = [
|
|
11
|
+
...document.adoptedStyleSheets,
|
|
12
|
+
appStyleSheet,
|
|
13
|
+
];
|
|
14
|
+
return () => {
|
|
15
|
+
document.adoptedStyleSheets = document.adoptedStyleSheets.filter(
|
|
16
|
+
(s) => s !== appStyleSheet,
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
}, []);
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div className="app">
|
|
23
|
+
<header className="app_header">
|
|
24
|
+
<img src={preactLogoUrl} className="app_logo" alt="logo" />
|
|
25
|
+
<p>Hello jsenv + preact!</p>
|
|
26
|
+
<p>
|
|
27
|
+
<Counter />
|
|
28
|
+
</p>
|
|
29
|
+
<p>
|
|
30
|
+
Edit{" "}
|
|
31
|
+
<a
|
|
32
|
+
className="app_link"
|
|
33
|
+
href="javascript:window.fetch('/__open_in_editor__/app/app.jsx')"
|
|
34
|
+
>
|
|
35
|
+
app.jsx
|
|
36
|
+
</a>{" "}
|
|
37
|
+
and save to test HMR updates.
|
|
38
|
+
</p>
|
|
39
|
+
<p>
|
|
40
|
+
<a
|
|
41
|
+
className="app_link"
|
|
42
|
+
href="https://github.com/jsenv/core"
|
|
43
|
+
target="_blank"
|
|
44
|
+
rel="noopener noreferrer"
|
|
45
|
+
>
|
|
46
|
+
Jsenv documentation
|
|
47
|
+
</a>
|
|
48
|
+
</p>
|
|
49
|
+
</header>
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Fragment } from "preact";
|
|
2
|
+
import { useState } from "preact/hooks";
|
|
3
|
+
|
|
4
|
+
export const Counter = () => {
|
|
5
|
+
const [count, setCount] = useState(0);
|
|
6
|
+
|
|
7
|
+
return (
|
|
8
|
+
<Fragment>
|
|
9
|
+
<button
|
|
10
|
+
id="counter_button"
|
|
11
|
+
type="button"
|
|
12
|
+
onClick={() => setCount((count) => count + 1)}
|
|
13
|
+
>
|
|
14
|
+
Click me
|
|
15
|
+
</button>
|
|
16
|
+
<br />
|
|
17
|
+
number of click: <span id="counter_output">{count}</span>
|
|
18
|
+
</Fragment>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="./preact_logo.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<style>
|
|
8
|
+
body {
|
|
9
|
+
margin: 0;
|
|
10
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
|
|
11
|
+
"Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
|
|
12
|
+
"Helvetica Neue", sans-serif;
|
|
13
|
+
-webkit-font-smoothing: antialiased;
|
|
14
|
+
-moz-osx-font-smoothing: grayscale;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
code {
|
|
18
|
+
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
|
19
|
+
monospace;
|
|
20
|
+
}
|
|
21
|
+
</style>
|
|
22
|
+
<title>Jsenv App</title>
|
|
23
|
+
</head>
|
|
24
|
+
<body>
|
|
25
|
+
<div id="root"></div>
|
|
26
|
+
<script type="module" src="./main.jsx"></script>
|
|
27
|
+
</body>
|
|
28
|
+
</html>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path fill="#673ab8" d="M16 2l12.12 7v14L16 30 3.88 23V9z"/>
|
|
3
|
+
<ellipse fill="none" stroke="#fff" cx="16" cy="16" rx="10.72" ry="4.1" transform="rotate(-37.5 16.007 15.996)"/>
|
|
4
|
+
<ellipse fill="none" stroke="#fff" cx="16" cy="16" rx="4.1" ry="10.72" transform="rotate(-52.5 15.998 15.994)"/>
|
|
5
|
+
<circle fill="#fff" cx="16" cy="16" r="1.86"/>
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
This HTML file demo how to write a test using jsenv.
|
|
3
|
+
This file is testing a "countDogs" function implemented in "animals.js"
|
|
4
|
+
-->
|
|
5
|
+
<!doctype html>
|
|
6
|
+
<html>
|
|
7
|
+
<head>
|
|
8
|
+
<meta charset="utf-8" />
|
|
9
|
+
<link rel="icon" href="data:," />
|
|
10
|
+
</head>
|
|
11
|
+
|
|
12
|
+
<body>
|
|
13
|
+
<script type="module">
|
|
14
|
+
import { assert } from "@jsenv/assert";
|
|
15
|
+
import "/app/animals.js";
|
|
16
|
+
|
|
17
|
+
{
|
|
18
|
+
const actual = window.countDogs(["dog", "dog"]);
|
|
19
|
+
const expect = 2;
|
|
20
|
+
assert({ actual, expect });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
{
|
|
24
|
+
const actual = window.countDogs(["dog", "cat"]);
|
|
25
|
+
const expect = 1;
|
|
26
|
+
assert({ actual, expect });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
document.body.appendChild(document.createTextNode("ok"));
|
|
30
|
+
</script>
|
|
31
|
+
</body>
|
|
32
|
+
</html>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { chromium } from "playwright";
|
|
2
|
+
import { assert } from "@jsenv/assert";
|
|
3
|
+
|
|
4
|
+
const browser = await chromium.launch();
|
|
5
|
+
|
|
6
|
+
try {
|
|
7
|
+
const browserContext = await browser.newContext({ ignoreHTTPSErrors: true });
|
|
8
|
+
const page = await browserContext.newPage();
|
|
9
|
+
await page.goto(`http://localhost:3400`);
|
|
10
|
+
|
|
11
|
+
const getCounterOutput = () => {
|
|
12
|
+
return page.locator("#counter_output").innerHTML();
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
assert({
|
|
16
|
+
actual: await getCounterOutput(),
|
|
17
|
+
expect: "0",
|
|
18
|
+
});
|
|
19
|
+
await page.locator("#counter_button").click();
|
|
20
|
+
assert({
|
|
21
|
+
actual: await getCounterOutput(),
|
|
22
|
+
expect: "1",
|
|
23
|
+
});
|
|
24
|
+
} finally {
|
|
25
|
+
browser.close();
|
|
26
|
+
}
|