glib-web 5.0.0 → 5.0.5
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 +8 -1
- package/actions/browsers/detectCountry.js +4 -1
- package/actions/dialogs/notification.js +4 -1
- package/actions/logics/run.js +4 -1
- package/actions/logics/set.js +6 -2
- package/agent/commands/generate_test.yaml +5 -5
- package/components/composable/date.js +4 -1
- package/components/datetime.vue +4 -1
- package/components/fields/phone/field.vue +4 -1
- package/components/mixins/styles.js +6 -2
- package/components/panels/bulkEdit2.vue +4 -1
- package/components/panels/custom.vue +1 -1
- package/components/popover.vue +49 -19
- package/components/shareButton.vue +4 -1
- package/components/treeView.vue +4 -1
- package/cypress/component/{inputUpload.cy.ts → inputUpload.cy.js} +3 -3
- package/cypress/component/{multiUpload.cy.ts → multiUpload.cy.js} +3 -3
- package/cypress/component/{placeholderUpload.cy.ts → placeholderUpload.cy.js} +3 -3
- package/cypress/component/{testUtils.ts → testUtils.js} +3 -15
- package/cypress/e2e/glib-web/{auth.cy.ts → auth.cy.js} +1 -1
- package/cypress/e2e/glib-web/{autoValidate.cy.ts → autoValidate.cy.js} +1 -1
- package/cypress/e2e/glib-web/{browsers.cy.ts → browsers.cy.js} +1 -1
- package/cypress/e2e/glib-web/{calendar.cy.ts → calendar.cy.js} +1 -1
- package/cypress/e2e/glib-web/{calendarEmptyData.cy.ts → calendarEmptyData.cy.js} +1 -1
- package/cypress/e2e/glib-web/{carousel.cy.ts → carousel.cy.js} +1 -1
- package/cypress/e2e/glib-web/{charts.cy.ts → charts.cy.js} +1 -1
- package/cypress/e2e/glib-web/{column.cy.ts → column.cy.js} +1 -1
- package/cypress/e2e/glib-web/{commands.cy.ts → commands.cy.js} +1 -1
- package/cypress/e2e/glib-web/{components.cy.ts → components.cy.js} +1 -1
- package/cypress/e2e/glib-web/{cookies.cy.ts → cookies.cy.js} +1 -1
- package/cypress/e2e/glib-web/{custom.cy.ts → custom.cy.js} +1 -1
- package/cypress/e2e/glib-web/dialog.cy.js +63 -0
- package/cypress/e2e/glib-web/{dialogOpen.cy.ts → dialogOpen.cy.js} +1 -1
- package/cypress/e2e/glib-web/{dirtyState.cy.ts → dirtyState.cy.js} +1 -1
- package/cypress/e2e/glib-web/{display.cy.ts → display.cy.js} +1 -1
- package/cypress/e2e/glib-web/{fields.cy.ts → fields.cy.js} +1 -1
- package/cypress/e2e/glib-web/{fieldsCaptcha.cy.ts → fieldsCaptcha.cy.js} +1 -1
- package/cypress/e2e/glib-web/{fieldsCreditCard.cy.ts → fieldsCreditCard.cy.js} +1 -1
- package/cypress/e2e/glib-web/{fieldsDateTime.cy.ts → fieldsDateTime.cy.js} +1 -1
- package/cypress/e2e/glib-web/{fieldsDynamicSelect.cy.ts → fieldsDynamicSelect.cy.js} +1 -1
- package/cypress/e2e/glib-web/{fieldsLocation.cy.ts → fieldsLocation.cy.js} +1 -1
- package/cypress/e2e/glib-web/{fieldsOtp.cy.ts → fieldsOtp.cy.js} +1 -1
- package/cypress/e2e/glib-web/{fieldsPhone.cy.ts → fieldsPhone.cy.js} +1 -1
- package/cypress/e2e/glib-web/{fieldsRating.cy.ts → fieldsRating.cy.js} +1 -1
- package/cypress/e2e/glib-web/{fieldsRichText.cy.ts → fieldsRichText.cy.js} +16 -17
- package/cypress/e2e/glib-web/{fieldsSelect.cy.ts → fieldsSelect.cy.js} +1 -1
- package/cypress/e2e/glib-web/{fieldsSign.cy.ts → fieldsSign.cy.js} +1 -1
- package/cypress/e2e/glib-web/{fieldsStripeToken.cy.ts → fieldsStripeToken.cy.js} +1 -1
- package/cypress/e2e/glib-web/{fieldsTimer.cy.ts → fieldsTimer.cy.js} +1 -1
- package/cypress/e2e/glib-web/{fieldsUpload.cy.ts → fieldsUpload.cy.js} +1 -1
- package/cypress/e2e/glib-web/{fieldsUrlFragment.cy.ts → fieldsUrlFragment.cy.js} +1 -1
- package/cypress/e2e/glib-web/{flow.cy.ts → flow.cy.js} +1 -1
- package/cypress/e2e/glib-web/{form.cy.ts → form.cy.js} +1 -1
- package/cypress/e2e/glib-web/{formDynamic.cy.ts → formDynamic.cy.js} +1 -1
- package/cypress/e2e/glib-web/{forms.cy.ts → forms.cy.js} +1 -1
- package/cypress/e2e/glib-web/{grid.cy.ts → grid.cy.js} +1 -1
- package/cypress/e2e/glib-web/{horizontal.cy.ts → horizontal.cy.js} +1 -1
- package/cypress/e2e/glib-web/{http.cy.ts → http.cy.js} +1 -1
- package/cypress/e2e/glib-web/{image.cy.ts → image.cy.js} +1 -1
- package/cypress/e2e/glib-web/{lifecycle.cy.ts → lifecycle.cy.js} +1 -1
- package/cypress/e2e/glib-web/{list.cy.ts → list.cy.js} +1 -1
- package/cypress/e2e/glib-web/{listEditable.cy.ts → listEditable.cy.js} +1 -1
- package/cypress/e2e/glib-web/{listsAppend.cy.ts → listsAppend.cy.js} +1 -1
- package/cypress/e2e/glib-web/{logicsSet.cy.ts → logicsSet.cy.js} +1 -1
- package/cypress/e2e/glib-web/{multimediaVideo.cy.ts → multimediaVideo.cy.js} +1 -1
- package/cypress/e2e/glib-web/{pagination.cy.ts → pagination.cy.js} +1 -1
- package/cypress/e2e/glib-web/{panels.cy.ts → panels.cy.js} +1 -1
- package/cypress/e2e/glib-web/{panelsBulkEdit2.cy.ts → panelsBulkEdit2.cy.js} +1 -1
- package/cypress/e2e/glib-web/{popovers.cy.ts → popovers.cy.js} +1 -1
- package/cypress/e2e/glib-web/{progressCircle.cy.ts → progressCircle.cy.js} +1 -1
- package/cypress/e2e/glib-web/{responsive.cy.ts → responsive.cy.js} +1 -1
- package/cypress/e2e/glib-web/{scroll.cy.ts → scroll.cy.js} +1 -1
- package/cypress/e2e/glib-web/{selectable.cy.ts → selectable.cy.js} +1 -1
- package/cypress/e2e/glib-web/{sheets.cy.ts → sheets.cy.js} +1 -1
- package/cypress/e2e/glib-web/{snackbars.cy.ts → snackbars.cy.js} +1 -1
- package/cypress/e2e/glib-web/{split.cy.ts → split.cy.js} +1 -1
- package/cypress/e2e/glib-web/{storageItems.cy.ts → storageItems.cy.js} +1 -1
- package/cypress/e2e/glib-web/{table.cy.ts → table.cy.js} +1 -1
- package/cypress/e2e/glib-web/{timeline.cy.ts → timeline.cy.js} +1 -1
- package/cypress/e2e/glib-web/{timeouts.cy.ts → timeouts.cy.js} +1 -1
- package/cypress/e2e/glib-web/{ul.cy.ts → ul.cy.js} +1 -1
- package/cypress/e2e/glib-web/{vertical.cy.ts → vertical.cy.js} +1 -1
- package/cypress/e2e/glib-web/{web.cy.ts → web.cy.js} +1 -1
- package/cypress/e2e/glib-web/{window.cy.ts → window.cy.js} +1 -1
- package/cypress/e2e/glib-web/{windows.cy.ts → windows.cy.js} +1 -1
- package/cypress/support/{commands.ts → commands.js} +2 -2
- package/cypress/support/{component.ts → component.js} +3 -3
- package/cypress/support/{e2e.ts → e2e.js} +3 -3
- package/{cypress.config.ts → cypress.config.js} +3 -2
- package/cypress.yml.example +6 -7
- package/doc/TESTING.md +2 -2
- package/index.js +4 -1
- package/package.json +1 -1
- package/templates/unsupported.vue +2 -2
- package/utils/eventBus.js +4 -1
- package/utils/hash.js +4 -1
- package/utils/interop.js +9 -0
- package/cypress/e2e/glib-web/dialog.cy.ts +0 -63
- /package/cypress/{helper.ts → helper.js} +0 -0
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import { testPageUrl, withComponent } from "../../helper"
|
|
1
|
+
import { testPageUrl, withComponent } from "../../helper.js"
|
|
2
2
|
|
|
3
3
|
const url = testPageUrl('fields_richText')
|
|
4
|
+
const csvFixtureContents = [
|
|
5
|
+
'month,electricity_usage,gas_usage,sources,compliant',
|
|
6
|
+
'January,120,10,Generators,yes',
|
|
7
|
+
'February,150,12,Solar Panels,no'
|
|
8
|
+
].join('\n')
|
|
4
9
|
|
|
5
10
|
describe('fields_richText', () => {
|
|
6
11
|
it('switches output variants', () => {
|
|
@@ -93,14 +98,11 @@ describe('fields_richText', () => {
|
|
|
93
98
|
cy.intercept('POST', uploader.blobUrlGenerator, { statusCode: 200, body: { url: 'https://example.com/blob' } }).as('blobUrl')
|
|
94
99
|
})
|
|
95
100
|
|
|
96
|
-
cy.
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
dataTransfer.items.add(file)
|
|
102
|
-
cy.get('#rich_text_main .ql-editor').trigger('drop', { dataTransfer })
|
|
103
|
-
})
|
|
101
|
+
cy.window().then((win) => {
|
|
102
|
+
const file = new win.File([csvFixtureContents], 'bulk_edit.csv', { type: 'text/csv' })
|
|
103
|
+
const dataTransfer = new win.DataTransfer()
|
|
104
|
+
dataTransfer.items.add(file)
|
|
105
|
+
cy.get('#rich_text_main .ql-editor').trigger('drop', { dataTransfer })
|
|
104
106
|
})
|
|
105
107
|
|
|
106
108
|
cy.wait('@directUpload')
|
|
@@ -109,14 +111,11 @@ describe('fields_richText', () => {
|
|
|
109
111
|
cy.get('input[name="user[images_attributes][]"]').should('have.length', 1)
|
|
110
112
|
cy.get('input[name="user[images_attributes][]"]').first().should('have.value', 'signed-1')
|
|
111
113
|
|
|
112
|
-
cy.
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
clipboardData.items.add(file)
|
|
118
|
-
cy.get('#rich_text_main .ql-editor').trigger('paste', { clipboardData })
|
|
119
|
-
})
|
|
114
|
+
cy.window().then((win) => {
|
|
115
|
+
const file = new win.File([csvFixtureContents], 'bulk_edit.csv', { type: 'text/csv' })
|
|
116
|
+
const clipboardData = new win.DataTransfer()
|
|
117
|
+
clipboardData.items.add(file)
|
|
118
|
+
cy.get('#rich_text_main .ql-editor').trigger('paste', { clipboardData })
|
|
120
119
|
})
|
|
121
120
|
|
|
122
121
|
cy.wait('@directUpload')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="cypress" />
|
|
2
2
|
// ***********************************************
|
|
3
|
-
// This example commands.
|
|
3
|
+
// This example commands.js shows you how to
|
|
4
4
|
// create various custom commands and overwrite
|
|
5
5
|
// existing commands.
|
|
6
6
|
//
|
|
@@ -34,4 +34,4 @@
|
|
|
34
34
|
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
|
|
35
35
|
// }
|
|
36
36
|
// }
|
|
37
|
-
// }
|
|
37
|
+
// }
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import "./commands";
|
|
2
|
-
import "@cypress/code-coverage/support";
|
|
1
|
+
import "./commands.js";
|
|
2
|
+
import "@cypress/code-coverage/support.js";
|
|
3
3
|
import { isFunction, isObject } from "../../utils/type.js";
|
|
4
4
|
|
|
5
|
-
const win = window
|
|
5
|
+
const win = window;
|
|
6
6
|
|
|
7
7
|
if (!win.__settings) {
|
|
8
8
|
win.__settings = { theme: {} };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// ***********************************************************
|
|
2
|
-
// This example support/e2e.
|
|
2
|
+
// This example support/e2e.js is processed and
|
|
3
3
|
// loaded automatically before your test files.
|
|
4
4
|
//
|
|
5
5
|
// This is a great place to put global configuration and
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
// ***********************************************************
|
|
15
15
|
|
|
16
16
|
// Import commands.js using ES2015 syntax:
|
|
17
|
-
import
|
|
18
|
-
import
|
|
17
|
+
import "./commands.js";
|
|
18
|
+
import "@cypress/code-coverage/support.js";
|
|
19
19
|
import { isFunction, isObject } from "../../utils/type.js";
|
|
20
20
|
|
|
21
21
|
Cypress.on("window:before:load", (win) => {
|
|
@@ -43,8 +43,8 @@ export default defineConfig({
|
|
|
43
43
|
},
|
|
44
44
|
},
|
|
45
45
|
},
|
|
46
|
-
specPattern: "cypress/component/**/*.cy.{js,jsx
|
|
47
|
-
supportFile: "cypress/support/component.
|
|
46
|
+
specPattern: "cypress/component/**/*.cy.{js,jsx}",
|
|
47
|
+
supportFile: "cypress/support/component.js",
|
|
48
48
|
setupNodeEvents(on, config) {
|
|
49
49
|
codeCoverageTask(on, config);
|
|
50
50
|
return config;
|
|
@@ -55,6 +55,7 @@ export default defineConfig({
|
|
|
55
55
|
pageLoadTimeout: 60000,
|
|
56
56
|
requestTimeout: 15000,
|
|
57
57
|
responseTimeout: 15000,
|
|
58
|
+
specPattern: "cypress/e2e/**/*.cy.{js,jsx}",
|
|
58
59
|
setupNodeEvents(on, config) {
|
|
59
60
|
codeCoverageTask(on, config);
|
|
60
61
|
return config;
|
package/cypress.yml.example
CHANGED
|
@@ -5,7 +5,7 @@ on:
|
|
|
5
5
|
- "yarn.lock"
|
|
6
6
|
- ".github/workflows/cypress.yml"
|
|
7
7
|
jobs:
|
|
8
|
-
|
|
8
|
+
cypress-test:
|
|
9
9
|
env:
|
|
10
10
|
RAILS_ENV: test
|
|
11
11
|
POSTGRES_USER: postgres
|
|
@@ -27,26 +27,25 @@ jobs:
|
|
|
27
27
|
--health-timeout 5s
|
|
28
28
|
--health-retries 5
|
|
29
29
|
steps:
|
|
30
|
-
- uses: actions/checkout@
|
|
30
|
+
- uses: actions/checkout@v6
|
|
31
31
|
- name: Setup Ruby
|
|
32
32
|
uses: ruby/setup-ruby@v1
|
|
33
33
|
with:
|
|
34
34
|
ruby-version: 3.2.1
|
|
35
35
|
bundler-cache: true
|
|
36
36
|
- name: Setup Node
|
|
37
|
-
uses: actions/setup-node@
|
|
37
|
+
uses: actions/setup-node@v6
|
|
38
38
|
with:
|
|
39
39
|
cache: "yarn"
|
|
40
|
-
node-version:
|
|
40
|
+
node-version: 24.11.1
|
|
41
41
|
- run: yarn install --frozen-lockfile
|
|
42
42
|
- run: sudo apt-get -yqq install libpq-dev
|
|
43
43
|
- run: cp config/database.yml.github-actions config/database.yml
|
|
44
44
|
- run: bundle exec rake db:test:prepare
|
|
45
45
|
- run: bundle exec rails server -d
|
|
46
|
+
- run: until curl -s http://localhost:3000 >/dev/null; do sleep 1; done
|
|
46
47
|
- name: Cypress run (e2e)
|
|
47
|
-
run: env -u ELECTRON_RUN_AS_NODE yarn cypress run --browser chrome
|
|
48
|
-
- name: Cypress run (component)
|
|
49
|
-
run: env -u ELECTRON_RUN_AS_NODE yarn cypress run --component
|
|
48
|
+
run: env -u ELECTRON_RUN_AS_NODE yarn run cypress run --browser chrome
|
|
50
49
|
- name: Upload screenshots
|
|
51
50
|
uses: actions/upload-artifact@v4
|
|
52
51
|
if: failure()
|
package/doc/TESTING.md
CHANGED
|
@@ -21,8 +21,8 @@ This is fundamentally different from typical frontend testing (Jest/Vitest with
|
|
|
21
21
|
|
|
22
22
|
### 3. **Test Page as Contract**
|
|
23
23
|
Each Cypress test has a **matching backend test page** (jbuilder file):
|
|
24
|
-
- `form.cy.
|
|
25
|
-
- `dialog.cy.
|
|
24
|
+
- `form.cy.js` → `test_page/form.json.jbuilder`
|
|
25
|
+
- `dialog.cy.js` → `test_page/dialog.json.jbuilder`
|
|
26
26
|
|
|
27
27
|
The test page acts as the **contract** between frontend and backend tests.
|
|
28
28
|
|
package/index.js
CHANGED
|
@@ -8,7 +8,10 @@ import { jsonView, vueApp } from "./store";
|
|
|
8
8
|
import './app.scss';
|
|
9
9
|
|
|
10
10
|
// lib for deep merge
|
|
11
|
-
import
|
|
11
|
+
import * as mergeModule from 'lodash.merge';
|
|
12
|
+
import { interopDefault } from "./utils/interop.js";
|
|
13
|
+
|
|
14
|
+
const merge = interopDefault(mergeModule);
|
|
12
15
|
|
|
13
16
|
const APP_ID = 'app';
|
|
14
17
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div>Unsupported template: {{
|
|
2
|
+
<div>Unsupported template: {{ compName }}</div>
|
|
3
3
|
</template>
|
|
4
4
|
|
|
5
5
|
<script>
|
|
6
6
|
export default {
|
|
7
7
|
props: {
|
|
8
8
|
spec: { type: Object, required: true },
|
|
9
|
-
|
|
9
|
+
compName: { type: String, required: true }
|
|
10
10
|
}
|
|
11
11
|
};
|
|
12
12
|
</script>
|
package/utils/eventBus.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
// eventBus.js
|
|
2
|
-
import
|
|
2
|
+
import * as EventEmitter2Module from "eventemitter2";
|
|
3
|
+
import { interopDefaultOr } from "./interop.js";
|
|
4
|
+
|
|
5
|
+
const EventEmitter2 = interopDefaultOr(EventEmitter2Module, "EventEmitter2");
|
|
3
6
|
|
|
4
7
|
const emitter = new EventEmitter2({ delimiter: '-', maxListeners: 0 });
|
|
5
8
|
|
package/utils/hash.js
CHANGED
package/utils/interop.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function interopDefault(moduleRef) {
|
|
2
|
+
return moduleRef && moduleRef.default ? moduleRef.default : moduleRef;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function interopDefaultOr(moduleRef, namedExport) {
|
|
6
|
+
if (moduleRef && moduleRef.default) return moduleRef.default;
|
|
7
|
+
if (moduleRef && moduleRef[namedExport]) return moduleRef[namedExport];
|
|
8
|
+
return moduleRef;
|
|
9
|
+
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { testPageUrl } from "../../helper"
|
|
2
|
-
import * as Type from "../../../utils/type.js"
|
|
3
|
-
const url = testPageUrl('dialog')
|
|
4
|
-
|
|
5
|
-
describe('dialog', () => {
|
|
6
|
-
it('updateExisting', () => {
|
|
7
|
-
cy.visit(url)
|
|
8
|
-
cy.contains('Dialog updateExisting').click()
|
|
9
|
-
cy.get('.v-dialog h1').should('contain.text', 'Hello world')
|
|
10
|
-
cy.get('.v-dialog .v-icon').should('exist')
|
|
11
|
-
cy.get('.v-dialog').contains('change dialog content').click()
|
|
12
|
-
cy.get('.v-dialog h1').should('contain.text', 'Hello world (updated)')
|
|
13
|
-
cy.get('.v-dialog .v-icon').should('not.exist')
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
it('open dialog', () => {
|
|
17
|
-
cy.visit(url)
|
|
18
|
-
cy.contains('Dialog open').click()
|
|
19
|
-
cy.get('.dialog-title > .close-btn').click()
|
|
20
|
-
|
|
21
|
-
cy.contains('Dialog open').click()
|
|
22
|
-
cy.get('.v-dialog').contains('close').click()
|
|
23
|
-
|
|
24
|
-
cy.get('.v-dialog').should('not.exist')
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('closeAll', () => {
|
|
28
|
-
cy.visit(url)
|
|
29
|
-
cy.contains('Dialog closeAll').click()
|
|
30
|
-
cy.get('.v-dialog', { timeout: 2000 }).should('exist')
|
|
31
|
-
cy.get('.v-dialog', { timeout: 4000 }).should('not.exist')
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
it('reload', () => {
|
|
35
|
-
cy.visit(url)
|
|
36
|
-
cy.contains('Dialog reload').click()
|
|
37
|
-
cy.get('.v-dialog').should('exist')
|
|
38
|
-
cy.get('.v-dialog').contains('Title')
|
|
39
|
-
cy.wait(1200)
|
|
40
|
-
cy.get('.v-dialog').should('exist')
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
it('notification triggers dialog alert', () => {
|
|
44
|
-
cy.visit(url)
|
|
45
|
-
|
|
46
|
-
cy.window().then((win) => {
|
|
47
|
-
if (Type.isNull(win.Push)) {
|
|
48
|
-
win.Push = { create: () => Promise.resolve() }
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
cy.stub(win.Push, 'create').callsFake((_title, options) => {
|
|
52
|
-
if (Type.isObject(options) && Type.isFunction(options.onClick)) {
|
|
53
|
-
options.onClick.call({ close: () => { } })
|
|
54
|
-
}
|
|
55
|
-
return Promise.resolve()
|
|
56
|
-
})
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
cy.contains('Dialog notification').click()
|
|
60
|
-
// cy.contains('.v-dialog', 'Perform action').should('exist')
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
})
|
|
File without changes
|