glib-web 5.0.7 → 6.0.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.
Files changed (58) hide show
  1. package/.claude/commands/gen-cypress-test.md +101 -0
  2. package/.github/dependabot.yml +24 -12
  3. package/.nycrc.json +4 -0
  4. package/AGENTS.md +1 -0
  5. package/README.md +4 -0
  6. package/actions/logics/set.js +5 -0
  7. package/actions/panels/scrollTo.js +2 -2
  8. package/actions/timeouts/set.js +1 -1
  9. package/app.scss +19 -0
  10. package/app.vue +1 -1
  11. package/components/charts/series.js +2 -2
  12. package/components/composable/gmap.js +1 -1
  13. package/components/composable/upload.js +1 -4
  14. package/components/composable/upload_nothing.js +1 -1
  15. package/components/fields/_buttonDate.vue +2 -2
  16. package/components/fields/_patternText.vue +2 -8
  17. package/components/fields/_select.vue +10 -8
  18. package/components/fields/_selectItemDefault.vue +1 -3
  19. package/components/fields/_selectItemWithIcon.vue +1 -3
  20. package/components/fields/_selectItemWithImage.vue +1 -3
  21. package/components/fields/clipboardUpload.vue +115 -0
  22. package/components/fields/dynamicGroup2.vue +1 -1
  23. package/components/fields/multiUpload.vue +12 -19
  24. package/components/fields/placeholderUpload.vue +8 -4
  25. package/components/fields/radioGroup.vue +0 -7
  26. package/components/fields/sign.vue +1 -1
  27. package/components/fields/text.vue +1 -9
  28. package/components/fields/upload.vue +4 -0
  29. package/components/mixins/longClick.js +1 -1
  30. package/components/panels/bulkEdit2.vue +1 -1
  31. package/components/panels/flow.vue +19 -10
  32. package/components/panels/list.vue +1 -1
  33. package/components/popover.vue +1 -1
  34. package/components/responsive.vue +1 -1
  35. package/cypress/e2e/glib-web/dialog.cy.js +0 -1
  36. package/cypress/e2e/glib-web/dirtyState.cy.js +37 -37
  37. package/cypress/e2e/glib-web/fieldsDateTime.cy.js +46 -3
  38. package/cypress/e2e/glib-web/fieldsRadio.cy.js +65 -0
  39. package/cypress/e2e/glib-web/fieldsSelect.cy.js +116 -76
  40. package/cypress/e2e/glib-web/fieldsText.cy.js +83 -0
  41. package/cypress/e2e/glib-web/fieldsUpload.cy.js +230 -120
  42. package/cypress/e2e/glib-web/image.cy.js +62 -33
  43. package/cypress/e2e/glib-web/switch.cy.js +13 -0
  44. package/cypress/e2e/glib-web/tabBar.cy.js +23 -0
  45. package/cypress/fixtures/document.pdf +12 -0
  46. package/cypress/fixtures/large.png +0 -0
  47. package/cypress/fixtures/upload.png +0 -0
  48. package/cypress/helper.js +13 -1
  49. package/cypress/support/component.js +1 -1
  50. package/cypress/support/e2e.js +20 -13
  51. package/doc/dependabot.md +22 -0
  52. package/eslint-rules/index.js +6 -6
  53. package/nav/dialog.vue +1 -1
  54. package/package.json +18 -16
  55. package/templates/_menu.vue +2 -2
  56. package/cypress/component/inputUpload.cy.js +0 -103
  57. package/cypress/component/multiUpload.cy.js +0 -107
  58. package/cypress/component/placeholderUpload.cy.js +0 -91
@@ -1,82 +1,122 @@
1
- import { testPageUrl } from "../../helper.js"
1
+ import { testPageUrl } from "../../helper.js";
2
2
 
3
- const url = testPageUrl('fields_select')
4
-
5
- const getSelectComponent = () =>
6
- cy.window().then((win) => {
7
- const comp = win.GLib.component.findById('select_media')
8
- expect(comp).to.exist
9
- return comp
10
- })
3
+ const url = testPageUrl('fields_select');
11
4
 
12
5
  describe('fields_select', () => {
13
6
  it('updates option variants', () => {
14
- cy.visit(url)
15
-
16
- cy.contains('Use icon options').click()
17
- getSelectComponent().then((comp) => {
18
- expect(comp.spec.options).to.have.length(4)
19
- expect(comp.spec.options[0].icon.name).to.eq('star')
20
- expect(comp.spec.multiple).to.not.eq(true)
21
- expect(comp.spec.useChips).to.not.eq(true)
22
- })
23
-
24
- cy.contains('Use image options').click()
25
- getSelectComponent().then((comp) => {
26
- expect(comp.spec.options).to.have.length(4)
27
- expect(comp.spec.options[0].imageUrl).to.contain('select-1')
28
- expect(comp.spec.multiple).to.not.eq(true)
29
- expect(comp.spec.useChips).to.not.eq(true)
30
- })
31
-
32
- cy.contains('Text only').click()
33
- getSelectComponent().then((comp) => {
34
- expect(comp.spec.options).to.have.length(4)
35
- expect(comp.spec.options[0].icon).to.be.undefined
36
- expect(comp.spec.options[0].imageUrl).to.be.undefined
37
- // expect(comp.spec.value).to.eq('option3')
38
- expect(comp.spec.multiple).to.not.eq(true)
39
- expect(comp.spec.useChips).to.not.eq(true)
40
- })
41
-
42
- cy.contains('Multiple + chips').click()
43
- getSelectComponent().then((comp) => {
44
- expect(comp.spec.options).to.have.length(4)
45
- expect(comp.spec.options[0].icon.name).to.eq('star')
46
- // expect(comp.spec.value).to.deep.equal(['option1', 'option3'])
47
- expect(comp.spec.multiple).to.eq(true)
48
- expect(comp.spec.useChips).to.eq(true)
49
- })
50
- })
7
+ cy.visit(url);
8
+
9
+ cy.contains('Use icon options').click();
10
+ cy.get('#select_media select[hidden] option').should('have.length', 4);
11
+ cy.get('#select_media').click();
12
+ cy.get('body').type('{esc}');
13
+ cy.get('#select_media .v-select--multiple').should('not.exist');
14
+ cy.get('#select_media .v-chip').should('not.exist');
15
+
16
+ cy.contains('Use image options').click();
17
+ cy.get('#select_media select[hidden] option').should('have.length', 4);
18
+ cy.get('#select_media').click();
19
+ cy.get('.v-overlay--active .v-list-item').first().find('img').should('have.attr', 'src').and('contain', 'select-1');
20
+ cy.get('body').type('{esc}');
21
+ cy.get('#select_media .v-select--multiple').should('not.exist');
22
+ cy.get('#select_media .v-chip').should('not.exist');
23
+
24
+ cy.contains('Text only').click();
25
+ cy.get('#select_media select[hidden] option').should('have.length', 4);
26
+ cy.get('#select_media').click();
27
+ cy.get('.v-overlay--active .v-list-item').first().find('.v-icon').should('not.exist');
28
+ cy.get('.v-overlay--active .v-list-item').first().find('img').should('not.exist');
29
+ cy.get('body').type('{esc}');
30
+ cy.get('#select_media .v-select--multiple').should('not.exist');
31
+ cy.get('#select_media .v-chip').should('not.exist');
32
+
33
+ cy.contains('Multiple + chips').click();
34
+ cy.get('#select_media select[hidden] option').should('have.length', 4);
35
+ cy.get('#select_media').click();
36
+ cy.get('body').type('{esc}');
37
+ cy.get('#select_media .v-select--multiple').should('exist');
38
+ cy.get('#select_media .v-chip').should('exist');
39
+ });
40
+
41
+ it('selects all options in multiple mode', () => {
42
+ cy.on('uncaught:exception', (err) => {
43
+ if (err.message.includes('ResizeObserver')) return false;
44
+ });
45
+
46
+ cy.visit(url);
47
+
48
+ cy.contains('Multiple + chips').click();
49
+ cy.get('#select_media').click();
50
+ cy.get('.v-list-item').contains('Option 2').click();
51
+ cy.get('.v-list-item').contains('Option 4').click();
52
+ cy.get('body').type('{esc}');
53
+
54
+ cy.get('#select_media input[type="hidden"]').should('have.length', 4);
55
+ cy.get('#select_media input[type="hidden"]').eq(0).should('have.value', 'option1');
56
+ cy.get('#select_media input[type="hidden"]').eq(1).should('have.value', 'option3');
57
+ cy.get('#select_media input[type="hidden"]').eq(2).should('have.value', 'option2');
58
+ cy.get('#select_media input[type="hidden"]').eq(3).should('have.value', 'option4');
59
+ });
60
+
61
+ it('removes one chip from multiple selection', () => {
62
+ cy.visit(url);
63
+
64
+ cy.contains('Multiple + chips').click();
65
+ cy.get('#select_media').contains('.v-chip', 'Option 1').should('exist');
66
+ cy.get('#select_media').contains('.v-chip', 'Option 1').find('[data-testid="close-chip"]').click();
67
+ cy.get('#select_media').contains('.v-chip', 'Option 1').should('not.exist');
68
+ cy.get('#select_media input[type="hidden"][value="option1"]').should('not.exist');
69
+ });
70
+
71
+ it('collapses expanded chips back to overflow state', () => {
72
+ cy.on('uncaught:exception', (err) => {
73
+ if (err.message.includes('ResizeObserver')) return false;
74
+ });
75
+
76
+ cy.visit(url);
77
+
78
+ cy.contains('Multiple + chips').click();
79
+
80
+ // Initial collapsed state: overflow chip shows "X more"
81
+ cy.get('#select_media .expansion-chip').should('contain.text', 'more');
82
+ cy.get('#select_media').contains('.expansion-chip', 'Show less').should('not.exist');
83
+
84
+ // Expand: click the "X more" chip
85
+ cy.get('#select_media .expansion-chip').click();
86
+ cy.get('body').type('{esc}');
87
+
88
+ // Expanded state: "Show less" chip is visible, "X more" is gone
89
+ cy.get('#select_media .expansion-chip').should('contain.text', 'Show less');
90
+ cy.get('#select_media').contains('.expansion-chip', 'more').should('not.exist');
91
+
92
+ // Collapse: click "Show less" (calls collapseChips)
93
+ cy.get('#select_media .expansion-chip').click();
94
+ cy.get('body').type('{esc}');
95
+
96
+ // Back to collapsed state
97
+ cy.get('#select_media .expansion-chip').should('contain.text', 'more');
98
+ cy.get('#select_media').contains('.expansion-chip', 'Show less').should('not.exist');
99
+ });
51
100
 
52
101
  it('toggles disabled and resets options', () => {
53
- cy.visit(url)
54
-
55
- cy.contains('Disable select').click()
56
- getSelectComponent().then((comp) => {
57
- expect(comp.spec.disabled).to.eq(true)
58
- })
59
- cy.get('#select_media').find('.v-input--disabled').should('exist')
60
-
61
- cy.contains('Enable select').click()
62
- getSelectComponent().then((comp) => {
63
- expect(comp.spec.disabled).to.not.eq(true)
64
- })
65
- cy.get('#select_media').find('.v-input--disabled').should('not.exist')
66
-
67
- cy.contains('Empty options').click()
68
- getSelectComponent().then((comp) => {
69
- expect(comp.spec.options).to.have.length(0)
70
- })
71
-
72
- cy.contains('Restore defaults').click()
73
- getSelectComponent().then((comp) => {
74
- expect(comp.spec.options).to.have.length(4)
75
- expect(comp.spec.options[0].icon.name).to.eq('star')
76
- expect(comp.fieldModel).to.eq('option1')
77
- expect(comp.spec.disabled).to.not.eq(true)
78
- expect(comp.spec.multiple).to.not.eq(true)
79
- expect(comp.spec.useChips).to.not.eq(true)
80
- })
81
- })
82
- })
102
+ cy.visit(url);
103
+
104
+ cy.contains('Disable select').click();
105
+ cy.get('#select_media').find('.v-input--disabled').should('exist');
106
+
107
+ cy.contains('Enable select').click();
108
+ cy.get('#select_media').find('.v-input--disabled').should('not.exist');
109
+
110
+ cy.contains('Empty options').click();
111
+ cy.get('#select_media select[hidden] option').should('have.length', 0);
112
+
113
+ cy.contains('Restore defaults').click();
114
+ cy.get('#select_media select[hidden] option').should('have.length', 4);
115
+ cy.get('#select_media').click();
116
+ cy.get('body').type('{esc}');
117
+ cy.get('#select_media input[type="hidden"]').should('have.length', 1).and('have.value', 'option1');
118
+ cy.get('#select_media .v-input--disabled').should('not.exist');
119
+ cy.get('#select_media .v-select--multiple').should('not.exist');
120
+ cy.get('#select_media .v-chip').should('not.exist');
121
+ });
122
+ });
@@ -0,0 +1,83 @@
1
+ import { testPageUrl } from "../../helper.js";
2
+
3
+ const url = testPageUrl('fields_text');
4
+
5
+ describe('fields_text', () => {
6
+ it('shows status changed when Name field is edited', () => {
7
+ cy.visit(url);
8
+
9
+ cy.contains('Status: idle').should('exist');
10
+ cy.get('input[placeholder="Full name"]').type('John Doe');
11
+ cy.contains('Status: changed').should('exist');
12
+ });
13
+
14
+ it('Set value fills the Name field with Hello world', () => {
15
+ cy.visit(url);
16
+
17
+ cy.contains('Set value').click();
18
+ cy.get('input[placeholder="Full name"]').should('have.value', 'Hello world');
19
+ });
20
+
21
+ it('Clear value empties the Name field', () => {
22
+ cy.visit(url);
23
+
24
+ cy.contains('Set value').click();
25
+ cy.get('input[placeholder="Full name"]').should('have.value', 'Hello world');
26
+ cy.contains('Clear value').click();
27
+ cy.get('input[placeholder="Full name"]').should('have.value', '');
28
+ });
29
+
30
+ it('Focus button focuses the Name field', () => {
31
+ cy.visit(url);
32
+
33
+ cy.contains('Focus').click();
34
+ cy.get('input[placeholder="Full name"]').should('be.focused');
35
+ });
36
+
37
+ it('Reset button resets fields and shows status reset', () => {
38
+ cy.visit(url);
39
+
40
+ cy.get('input[placeholder="Full name"]').type('Changed text');
41
+ cy.contains('Reset').click();
42
+ cy.get('#text_status').scrollIntoView().should('contain', 'Status: reset');
43
+ cy.get('input[placeholder="Full name"]').should('have.value', '');
44
+ });
45
+
46
+ it('password visibility toggle reveals and hides password text', () => {
47
+ cy.visit(url);
48
+
49
+ cy.get('input[placeholder="Enter your password"]').type('secret123');
50
+ cy.get('input[placeholder="Enter your password"]').should('have.attr', 'type', 'password');
51
+ cy.get('input[placeholder="Enter your password"]')
52
+ .closest('.v-input')
53
+ .find('i.material-icons[role="button"]')
54
+ .click();
55
+ cy.get('input[placeholder="Enter your password"]').should('have.attr', 'type', 'text');
56
+ });
57
+
58
+ it('derived value updates when Base value changes', () => {
59
+ cy.visit(url);
60
+
61
+ cy.contains('Base value').closest('.v-input').find('input').clear().type('30');
62
+ cy.get('input[name="user[derived_value]"]').should('have.value', '10');
63
+ });
64
+
65
+ it('password strength hint appears when password reaches 8 characters', () => {
66
+ cy.visit(url);
67
+
68
+ cy.get('input[placeholder="Type a password..."]').type('short');
69
+ cy.contains('Password length looks good').should('not.be.visible');
70
+ cy.get('input[placeholder="Type a password..."]').type('longpass');
71
+ cy.contains('Password length looks good').should('be.visible');
72
+ });
73
+
74
+ it('Submit opens a dialog showing POST form data', () => {
75
+ cy.visit(url);
76
+
77
+ cy.contains('Submit').click();
78
+ cy.contains('Method: POST').should('be.visible');
79
+ cy.contains('Form Data:').should('be.visible');
80
+ cy.contains('OK').click();
81
+ cy.contains('Method: POST').should('not.exist');
82
+ });
83
+ });