@live-change/frontend-template 0.9.205 → 0.9.206

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.
@@ -1,7 +1,6 @@
1
- import test from 'node:test'
2
1
  import assert from 'node:assert'
2
+ import { e2eSuite, test } from '@live-change/e2e-test'
3
3
  import { withBrowser } from './withBrowser.js'
4
- import { e2eSuite } from './e2eSuite.js'
5
4
 
6
5
  e2eSuite('client-session', () => {
7
6
  test('frontend initializes api client session', async () => {
package/e2e/e2eSuite.ts CHANGED
@@ -1,12 +1,8 @@
1
- import { after, describe } from 'node:test'
2
- import { disposeTestEnv } from './env.js'
3
-
4
- export function e2eSuite(name: string, define: () => void): void {
5
- describe(name, () => {
6
- after(async () => {
7
- await disposeTestEnv()
8
- process.exit(0)
9
- })
10
- define()
11
- })
12
- }
1
+ export {
2
+ e2eSuite,
3
+ getE2ERegistry,
4
+ resetE2ERegistry,
5
+ setCurrentE2EFile,
6
+ test,
7
+ type E2ETestDefinition
8
+ } from '@live-change/e2e-test'
package/e2e/env.ts CHANGED
@@ -1,26 +1,10 @@
1
1
  import path from 'path'
2
2
  import { fileURLToPath } from 'url'
3
3
  import { TestServer } from '@live-change/server'
4
+ import { createTestEnvHelpers, waitForServerReady } from '@live-change/e2e-test'
4
5
  import appConfig from '../server/app.config.js'
5
6
  import * as services from '../server/services.list.js'
6
7
 
7
- const READY_TIMEOUT_MS = 60000
8
- const READY_POLL_MS = 2000
9
-
10
- async function waitForServerReady(url: string): Promise<void> {
11
- const deadline = Date.now() + READY_TIMEOUT_MS
12
- while (Date.now() < deadline) {
13
- try {
14
- const res = await fetch(url)
15
- if (res.ok) return
16
- } catch {
17
- // not ready yet
18
- }
19
- await new Promise((r) => setTimeout(r, READY_POLL_MS))
20
- }
21
- throw new Error(`Server at ${url} did not become ready within ${READY_TIMEOUT_MS}ms`)
22
- }
23
-
24
8
  const __dirname = path.dirname(fileURLToPath(import.meta.url))
25
9
  const serverDir = path.join(__dirname, '..', 'server')
26
10
  const frontDir = path.join(__dirname, '..', 'front')
@@ -49,22 +33,10 @@ let testServer: TestServerInstance | null = null
49
33
 
50
34
  export async function disposeTestEnv(): Promise<void> {
51
35
  const s = testServer
36
+ if (!s) return
52
37
  testServer = null
53
38
  envPromise = null
54
- if (s) await s.dispose()
55
- }
56
-
57
- function haveService(server: TestServerInstance, name: string) {
58
- const service = server.apiServer.services.services.find((s: { name: string }) => s.name === name)
59
- if (!service) throw new Error('service ' + name + ' not found')
60
- return service
61
- }
62
-
63
- function haveModel(server: TestServerInstance, serviceName: string, modelName: string) {
64
- const service = haveService(server, serviceName)
65
- const model = service.models[modelName]
66
- if (!model) throw new Error('model ' + modelName + ' not found')
67
- return model
39
+ await s.dispose()
68
40
  }
69
41
 
70
42
  export async function getTestEnv(): Promise<TestEnv> {
@@ -97,33 +69,16 @@ export async function getTestEnv(): Promise<TestEnv> {
97
69
  })
98
70
 
99
71
  const url = server.url!
72
+ const helpers = createTestEnvHelpers(server)
100
73
  return {
101
74
  server,
102
75
  url,
103
- haveService: (name: string) => haveService(server, name),
104
- haveModel: (serviceName: string, modelName: string) => haveModel(server, serviceName, modelName),
105
- haveView: (serviceName: string, viewName: string) => {
106
- const service = haveService(server, serviceName)
107
- const view = service.views[viewName]
108
- if (!view) throw new Error('view ' + viewName + ' not found')
109
- return view
110
- },
111
- haveAction: (serviceName: string, actionName: string) => {
112
- const service = haveService(server, serviceName)
113
- const action = service.actions[actionName]
114
- if (!action) throw new Error('action ' + actionName + ' not found')
115
- return action
116
- },
117
- haveTrigger: (serviceName: string, triggerName: string) => {
118
- const service = haveService(server, serviceName)
119
- const trigger = service.triggers[triggerName]
120
- if (!trigger) throw new Error('trigger ' + triggerName + ' not found')
121
- return trigger
122
- },
123
- grabObject: async (serviceName: string, modelName: string, id: string) => {
124
- const model = haveModel(server, serviceName, modelName)
125
- return await model.get(id)
126
- }
76
+ haveService: helpers.haveService,
77
+ haveModel: helpers.haveModel,
78
+ haveView: helpers.haveView,
79
+ haveAction: helpers.haveAction,
80
+ haveTrigger: helpers.haveTrigger,
81
+ grabObject: helpers.grabObject
127
82
  }
128
83
  })()
129
84
  return envPromise
@@ -1,7 +1,6 @@
1
- import test from 'node:test'
2
1
  import assert from 'node:assert'
2
+ import { e2eSuite, test } from '@live-change/e2e-test'
3
3
  import { withBrowser } from './withBrowser.js'
4
- import { e2eSuite } from './e2eSuite.js'
5
4
 
6
5
  e2eSuite('homepage', () => {
7
6
  test('homepage responds and renders html', async () => {
package/e2e/runner.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { createRunner } from '@live-change/e2e-test'
2
+ import { disposeTestEnv, getTestEnv } from './env.js'
3
+
4
+ const runner = createRunner({
5
+ setupEnv: getTestEnv,
6
+ teardownEnv: disposeTestEnv
7
+ })
8
+
9
+ export const runE2E = runner.runE2E
10
+ await runner.runCli(import.meta.url, process.argv.slice(2))
@@ -1,18 +1,5 @@
1
- import { chromium } from 'playwright'
2
- import type { Page } from 'playwright'
3
- import { getTestEnv, type TestEnv } from './env.js'
1
+ import { createWithBrowser } from '@live-change/e2e-test'
2
+ import { getTestEnv } from './env.js'
3
+ import type { TestEnv } from './env.js'
4
4
 
5
- export async function withBrowser(
6
- fn: (page: Page, env: TestEnv) => Promise<void>
7
- ): Promise<void> {
8
- const env = await getTestEnv()
9
- const browser = await chromium.launch({ headless: process.env.SHOW_BROWSER ? false : true })
10
- const context = await browser.newContext()
11
- const page = await context.newPage()
12
- try {
13
- await fn(page, env)
14
- } finally {
15
- await context.close()
16
- await browser.close()
17
- }
18
- }
5
+ export const withBrowser = createWithBrowser<TestEnv>(getTestEnv)
@@ -65,7 +65,7 @@
65
65
 
66
66
  <NotificationsIcon v-if="client.user" />
67
67
 
68
- <UserIcon v-if="client.user" />
68
+ <UserIcon v-if="client.user" :menuStyle="{ right: '5px' }" />
69
69
 
70
70
  <a v-ripple class="cursor-pointer flex items-center justify-content-center no-underline lg:hidden text-surface-700 dark:text-surface-100 p-ripple
71
71
  ml-2 hover:bg-surface-100 dark:hover:bg-surface-700 p-2"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/frontend-template",
3
- "version": "0.9.205",
3
+ "version": "0.9.206",
4
4
  "scripts": {
5
5
  "memDev": "tsx --inspect --expose-gc server/start.js memDev --enableSessions --initScript ./init.js --dbAccess",
6
6
  "localDevInit": "tsx server/start.js localDev --enableSessions --initScript ./init.js --dbAccess",
@@ -39,64 +39,66 @@
39
39
  "prerenderTsx": "cross-env NODE_ENV=production tsx server/start.js prerender --enableSessions",
40
40
  "prerenderMemTsx": "cross-env NODE_ENV=production tsx server/start.js prerender --enableSessions --withDb --dbBackend mem --createDb --withApi --withServices --updateServices",
41
41
  "prerenderLocalTsx": "cross-env NODE_ENV=production tsx server/start.js prerender --enableSessions --withDb --createDb --withApi --withServices --updateServices",
42
- "e2e": "tsx --test e2e/*.test.ts",
43
- "e2e:headed": "SHOW_BROWSER=1 tsx --test e2e/*.test.ts"
42
+ "e2e": "fnm exec -- node --import tsx e2e/runner.ts",
43
+ "e2e:headed": "SHOW_BROWSER=1 fnm exec -- node --import tsx e2e/runner.ts",
44
+ "e2e:file": "fnm exec -- node --import tsx e2e/runner.ts"
44
45
  },
45
46
  "type": "module",
46
47
  "dependencies": {
47
48
  "@codemirror/language": "6.12.3",
48
49
  "@dotenvx/dotenvx": "0.27.0",
49
50
  "@fortawesome/fontawesome-free": "^6.7.2",
50
- "@live-change/access-control-frontend": "^0.9.205",
51
- "@live-change/access-control-service": "^0.9.205",
52
- "@live-change/agreement-service": "^0.9.205",
53
- "@live-change/backup-service": "^0.9.205",
54
- "@live-change/blog-frontend": "^0.9.205",
55
- "@live-change/blog-service": "^0.9.205",
56
- "@live-change/cli": "^0.9.205",
57
- "@live-change/content-frontend": "^0.9.205",
58
- "@live-change/content-service": "^0.9.205",
59
- "@live-change/cron-service": "^0.9.205",
60
- "@live-change/dao": "^0.9.205",
61
- "@live-change/dao-vue3": "^0.9.205",
62
- "@live-change/dao-websocket": "^0.9.205",
63
- "@live-change/db-client": "^0.9.205",
64
- "@live-change/draft-service": "^0.9.205",
65
- "@live-change/email-service": "^0.9.205",
66
- "@live-change/framework": "^0.9.205",
67
- "@live-change/frontend-auto-form": "^0.9.205",
68
- "@live-change/frontend-base": "^0.9.205",
69
- "@live-change/geoip-service": "^0.9.205",
70
- "@live-change/google-authentication-service": "^0.9.205",
71
- "@live-change/image-frontend": "^0.9.205",
72
- "@live-change/linkedin-authentication-service": "^0.9.205",
73
- "@live-change/locale-settings-service": "^0.9.205",
74
- "@live-change/notification-service": "^0.9.205",
75
- "@live-change/password-authentication-service": "^0.9.205",
76
- "@live-change/peer-connection-frontend": "^0.9.205",
77
- "@live-change/peer-connection-service": "^0.9.205",
78
- "@live-change/prosemirror-service": "^0.9.205",
79
- "@live-change/scope-service": "^0.9.205",
80
- "@live-change/secret-code-service": "^0.9.205",
81
- "@live-change/secret-link-service": "^0.9.205",
82
- "@live-change/security-service": "^0.9.205",
83
- "@live-change/session-service": "^0.9.205",
84
- "@live-change/task-frontend": "^0.9.205",
85
- "@live-change/task-service": "^0.9.205",
86
- "@live-change/timer-service": "^0.9.205",
87
- "@live-change/upload-frontend": "^0.9.205",
88
- "@live-change/upload-service": "^0.9.205",
89
- "@live-change/url-frontend": "^0.9.205",
90
- "@live-change/url-service": "^0.9.205",
91
- "@live-change/user-frontend": "^0.9.205",
92
- "@live-change/user-identification-service": "^0.9.205",
93
- "@live-change/user-service": "^0.9.205",
94
- "@live-change/video-call-frontend": "^0.9.205",
95
- "@live-change/video-call-service": "^0.9.205",
96
- "@live-change/vote-service": "^0.9.205",
97
- "@live-change/vue3-components": "^0.9.205",
98
- "@live-change/vue3-ssr": "^0.9.205",
99
- "@live-change/wysiwyg-frontend": "^0.9.205",
51
+ "@live-change/access-control-frontend": "^0.9.206",
52
+ "@live-change/access-control-service": "^0.9.206",
53
+ "@live-change/agreement-service": "^0.9.206",
54
+ "@live-change/backup-service": "^0.9.206",
55
+ "@live-change/blog-frontend": "^0.9.206",
56
+ "@live-change/blog-service": "^0.9.206",
57
+ "@live-change/cli": "^0.9.206",
58
+ "@live-change/content-frontend": "^0.9.206",
59
+ "@live-change/content-service": "^0.9.206",
60
+ "@live-change/cron-service": "^0.9.206",
61
+ "@live-change/dao": "^0.9.206",
62
+ "@live-change/dao-vue3": "^0.9.206",
63
+ "@live-change/dao-websocket": "^0.9.206",
64
+ "@live-change/db-client": "^0.9.206",
65
+ "@live-change/draft-service": "^0.9.206",
66
+ "@live-change/e2e-test": "^0.9.206",
67
+ "@live-change/email-service": "^0.9.206",
68
+ "@live-change/framework": "^0.9.206",
69
+ "@live-change/frontend-auto-form": "^0.9.206",
70
+ "@live-change/frontend-base": "^0.9.206",
71
+ "@live-change/geoip-service": "^0.9.206",
72
+ "@live-change/google-authentication-service": "^0.9.206",
73
+ "@live-change/image-frontend": "^0.9.206",
74
+ "@live-change/linkedin-authentication-service": "^0.9.206",
75
+ "@live-change/locale-settings-service": "^0.9.206",
76
+ "@live-change/notification-service": "^0.9.206",
77
+ "@live-change/password-authentication-service": "^0.9.206",
78
+ "@live-change/peer-connection-frontend": "^0.9.206",
79
+ "@live-change/peer-connection-service": "^0.9.206",
80
+ "@live-change/prosemirror-service": "^0.9.206",
81
+ "@live-change/scope-service": "^0.9.206",
82
+ "@live-change/secret-code-service": "^0.9.206",
83
+ "@live-change/secret-link-service": "^0.9.206",
84
+ "@live-change/security-service": "^0.9.206",
85
+ "@live-change/session-service": "^0.9.206",
86
+ "@live-change/task-frontend": "^0.9.206",
87
+ "@live-change/task-service": "^0.9.206",
88
+ "@live-change/timer-service": "^0.9.206",
89
+ "@live-change/upload-frontend": "^0.9.206",
90
+ "@live-change/upload-service": "^0.9.206",
91
+ "@live-change/url-frontend": "^0.9.206",
92
+ "@live-change/url-service": "^0.9.206",
93
+ "@live-change/user-frontend": "^0.9.206",
94
+ "@live-change/user-identification-service": "^0.9.206",
95
+ "@live-change/user-service": "^0.9.206",
96
+ "@live-change/video-call-frontend": "^0.9.206",
97
+ "@live-change/video-call-service": "^0.9.206",
98
+ "@live-change/vote-service": "^0.9.206",
99
+ "@live-change/vue3-components": "^0.9.206",
100
+ "@live-change/vue3-ssr": "^0.9.206",
101
+ "@live-change/wysiwyg-frontend": "^0.9.206",
100
102
  "@vueuse/core": "^12.3.0",
101
103
  "codeceptjs-assert": "^0.0.5",
102
104
  "compression": "^1.7.5",
@@ -129,5 +131,5 @@
129
131
  "author": "Michał Łaszczewski <michal@laszczewski.pl>",
130
132
  "license": "ISC",
131
133
  "description": "",
132
- "gitHead": "ef195e51ea283e56d891b11da5d5f586691507db"
134
+ "gitHead": "550ec614c03ed33fbb8a094d23a63dd2d20d5de3"
133
135
  }