glib-web 4.42.1 → 4.42.2
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/.nycrc.json +20 -5
- package/action.js +0 -6
- package/agent/glib_test_sync.yaml +108 -0
- package/components/_internal_button.vue +6 -5
- package/components/component.vue +0 -1
- package/components/fields/_select.vue +10 -28
- package/components/fields/radioGroup.vue +1 -1
- package/components/multimedia/video.vue +13 -1
- package/cypress/component/component.cy.ts +0 -9
- package/cypress/e2e/glib-web/browsers.cy.ts +55 -0
- package/cypress/e2e/glib-web/calendar.cy.ts +34 -0
- package/cypress/e2e/glib-web/calendarEmptyData.cy.ts +10 -0
- package/cypress/e2e/glib-web/carousel.cy.ts +53 -0
- package/cypress/e2e/glib-web/charts.cy.ts +11 -0
- package/cypress/e2e/glib-web/column.cy.ts +27 -0
- package/cypress/e2e/glib-web/commands.cy.ts +35 -0
- package/cypress/e2e/glib-web/components.cy.ts +50 -0
- package/cypress/e2e/glib-web/custom.cy.ts +17 -0
- package/cypress/e2e/glib-web/dialogOpen.cy.ts +14 -0
- package/cypress/e2e/glib-web/fileUploadNew.cy.ts +12 -0
- package/cypress/e2e/glib-web/flow.cy.ts +29 -0
- package/cypress/e2e/glib-web/form.cy.ts +1 -1
- package/cypress/e2e/glib-web/forms.cy.ts +46 -0
- package/cypress/e2e/glib-web/grid.cy.ts +27 -0
- package/cypress/e2e/glib-web/horizontal.cy.ts +39 -0
- package/cypress/e2e/glib-web/http.cy.ts +55 -19
- package/cypress/e2e/glib-web/image.cy.ts +53 -0
- package/cypress/e2e/glib-web/list.cy.ts +41 -0
- package/cypress/e2e/glib-web/listsAppend.cy.ts +27 -0
- package/cypress/e2e/glib-web/multimediaVideo.cy.ts +43 -0
- package/cypress/e2e/glib-web/pagination.cy.ts +34 -0
- package/cypress/e2e/glib-web/panels.cy.ts +50 -0
- package/cypress/e2e/glib-web/popovers.cy.ts +34 -0
- package/cypress/e2e/glib-web/progressCircle.cy.ts +45 -0
- package/cypress/e2e/glib-web/responsive.cy.ts +21 -0
- package/cypress/e2e/glib-web/scroll.cy.ts +37 -0
- package/cypress/e2e/glib-web/sheets.cy.ts +77 -10
- package/cypress/e2e/glib-web/snackbars.cy.ts +33 -22
- package/cypress/e2e/glib-web/split.cy.ts +12 -0
- package/cypress/e2e/glib-web/storageItems.cy.ts +71 -0
- package/cypress/e2e/glib-web/table.cy.ts +28 -0
- package/cypress/e2e/glib-web/timeline.cy.ts +32 -0
- package/cypress/e2e/glib-web/timeouts.cy.ts +26 -0
- package/cypress/e2e/glib-web/ul.cy.ts +19 -0
- package/cypress/e2e/glib-web/vertical.cy.ts +41 -0
- package/cypress/e2e/glib-web/web.cy.ts +29 -0
- package/cypress/e2e/glib-web/windows.cy.ts +69 -0
- package/index.js +1 -5
- package/package.json +3 -3
- package/actions/global_states/set.js +0 -13
- package/actions/global_states/watch.js +0 -19
- package/actions/right_banners/close.js +0 -7
- package/actions/right_banners/open.js +0 -25
- package/components/fields/richText.vue +0 -361
- package/components/fields/select.vue +0 -27
- package/components/mixins/extension.js +0 -9
- package/components/panels/table2.vue +0 -113
package/.nycrc.json
CHANGED
|
@@ -9,10 +9,25 @@
|
|
|
9
9
|
".ts",
|
|
10
10
|
".vue"
|
|
11
11
|
],
|
|
12
|
+
"exclude-after-remap": true,
|
|
13
|
+
"include": [
|
|
14
|
+
"action.js",
|
|
15
|
+
"actions/**",
|
|
16
|
+
"app.vue",
|
|
17
|
+
"components/**",
|
|
18
|
+
"constant.js",
|
|
19
|
+
"extensions/**",
|
|
20
|
+
"index.js",
|
|
21
|
+
"keys.js",
|
|
22
|
+
"nav/**",
|
|
23
|
+
"plugins/**",
|
|
24
|
+
"store.js",
|
|
25
|
+
"templates/**",
|
|
26
|
+
"utils/**"
|
|
27
|
+
],
|
|
12
28
|
"exclude": [
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"node_modules/**"
|
|
29
|
+
"actions/cables",
|
|
30
|
+
"actions/analytics",
|
|
31
|
+
"utils/private"
|
|
17
32
|
]
|
|
18
|
-
}
|
|
33
|
+
}
|
package/action.js
CHANGED
|
@@ -85,9 +85,6 @@ import ActionListsAppend from "./actions/lists/append";
|
|
|
85
85
|
import ActionBottomBannersOpen from "./actions/bottom_banners/open";
|
|
86
86
|
import ActionBottomBannersClose from "./actions/bottom_banners/close";
|
|
87
87
|
|
|
88
|
-
import ActionGlobalStatesWatch from "./actions/global_states/watch";
|
|
89
|
-
import ActionGlobalStatesSet from "./actions/global_states/set";
|
|
90
|
-
|
|
91
88
|
import ActionDetectCountry from "./actions/browsers/detectCountry";
|
|
92
89
|
import ActionDetectTimezone from "./actions/browsers/detectTimezone";
|
|
93
90
|
|
|
@@ -189,9 +186,6 @@ const actions = {
|
|
|
189
186
|
"bottomBanners/open": ActionBottomBannersOpen,
|
|
190
187
|
"bottomBanners/close": ActionBottomBannersClose,
|
|
191
188
|
|
|
192
|
-
"globalStates/watch": ActionGlobalStatesWatch,
|
|
193
|
-
"globalStates/set": ActionGlobalStatesSet,
|
|
194
|
-
|
|
195
189
|
"files/upload": ActionFilesUpload,
|
|
196
190
|
|
|
197
191
|
"browsers/detectCountry": ActionDetectCountry,
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
version: 1
|
|
2
|
+
name: glib-web-test-sync
|
|
3
|
+
description: >
|
|
4
|
+
Compare doc/garage/test_page pages with Cypress tests in cypress/e2e/glib-web and
|
|
5
|
+
scaffold missing tests when a page exists without coverage.
|
|
6
|
+
|
|
7
|
+
inputs:
|
|
8
|
+
doc_dir: doc/garage/test_page
|
|
9
|
+
test_dir: cypress/e2e/glib-web
|
|
10
|
+
test_helper: cypress/helper.ts
|
|
11
|
+
ai_test_prompt: |
|
|
12
|
+
Generate a Cypress e2e test for the glib test page: {{page_slug}}.
|
|
13
|
+
Inputs you can use:
|
|
14
|
+
- Source: {{doc_page_path}}
|
|
15
|
+
- Existing tests: {{existing_tests_dir}}
|
|
16
|
+
Requirements:
|
|
17
|
+
- Must use: import { testPageUrl } from "../../helper"
|
|
18
|
+
- Must set: const url = testPageUrl('{{page_slug}}')
|
|
19
|
+
- Click every button defined in {{doc_page_path}} (include nested buttons in dialogs/sheets/menus).
|
|
20
|
+
- For each button click, assert the expected result implied by its onClick action.
|
|
21
|
+
- Use one or more it blocks; revisit the page when state needs a reset.
|
|
22
|
+
- Match existing project patterns (describe/it, cy.visit, selectors, etc).
|
|
23
|
+
- Use ASCII only.
|
|
24
|
+
fallback_test_template: |
|
|
25
|
+
import { testPageUrl } from "../../helper"
|
|
26
|
+
const url = testPageUrl('{{page_slug}}')
|
|
27
|
+
|
|
28
|
+
const overlaySelectors = [
|
|
29
|
+
'.v-dialog',
|
|
30
|
+
'.v-snackbar',
|
|
31
|
+
'.v-menu__content',
|
|
32
|
+
'.v-sheet',
|
|
33
|
+
'.v-overlay__content',
|
|
34
|
+
].join(',')
|
|
35
|
+
|
|
36
|
+
describe('{{page_slug}}', () => {
|
|
37
|
+
it('clicks each button', () => {
|
|
38
|
+
cy.visit(url)
|
|
39
|
+
cy.get('button').should('have.length.at.least', 1)
|
|
40
|
+
cy.get('button').then(($buttons) => {
|
|
41
|
+
const labels = Array.from($buttons)
|
|
42
|
+
.map((button) => button.innerText.trim())
|
|
43
|
+
.filter(Boolean)
|
|
44
|
+
|
|
45
|
+
cy.wrap(labels).each((label) => {
|
|
46
|
+
cy.visit(url)
|
|
47
|
+
cy.contains('button', label).click({ force: true })
|
|
48
|
+
cy.location('href').then((hrefAfter) => {
|
|
49
|
+
if (hrefAfter !== url) {
|
|
50
|
+
expect(hrefAfter).to.not.eq(url)
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
cy.get('body').then(($body) => {
|
|
55
|
+
if ($body.find(overlaySelectors).length) {
|
|
56
|
+
cy.get(overlaySelectors).should('exist')
|
|
57
|
+
} else {
|
|
58
|
+
cy.contains('button', label).should('exist')
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
})
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
constraints:
|
|
68
|
+
- Use utils/type.js for any type checks in helper scripts.
|
|
69
|
+
- Ignore files that begin with "_" under doc/garage/test_page.
|
|
70
|
+
|
|
71
|
+
steps:
|
|
72
|
+
- id: collect-doc-pages
|
|
73
|
+
instruction: |
|
|
74
|
+
List *.json.jbuilder files under {{inputs.doc_dir}}.
|
|
75
|
+
Remove the ".json.jbuilder" suffix to get page slugs.
|
|
76
|
+
Drop any file that starts with "_".
|
|
77
|
+
Output: doc_page_slugs.
|
|
78
|
+
|
|
79
|
+
- id: collect-test-page-slugs
|
|
80
|
+
instruction: |
|
|
81
|
+
Scan every *.cy.ts under {{inputs.test_dir}} and extract all occurrences of
|
|
82
|
+
testPageUrl('...'). Collect the string values into test_page_slugs.
|
|
83
|
+
If a file contains no testPageUrl calls, derive a fallback slug by:
|
|
84
|
+
- Removing the .cy.ts suffix.
|
|
85
|
+
- Converting camelCase to snake_case.
|
|
86
|
+
Output: test_page_slugs.
|
|
87
|
+
|
|
88
|
+
- id: diff-docs-vs-tests
|
|
89
|
+
instruction: |
|
|
90
|
+
Compute missing_page_slugs = doc_page_slugs - test_page_slugs.
|
|
91
|
+
Output: missing_page_slugs.
|
|
92
|
+
|
|
93
|
+
- id: generate-missing-test-content
|
|
94
|
+
instruction: |
|
|
95
|
+
For each slug in missing_page_slugs:
|
|
96
|
+
1) Set doc_page_path = {{inputs.doc_dir}}/<slug>.json.jbuilder.
|
|
97
|
+
2) Use the AI with {{inputs.ai_test_prompt}} to generate test content.
|
|
98
|
+
3) If AI output is empty or invalid, use {{inputs.fallback_test_template}}.
|
|
99
|
+
Output: generated_tests_map (slug -> test_content).
|
|
100
|
+
|
|
101
|
+
- id: scaffold-missing-tests
|
|
102
|
+
instruction: |
|
|
103
|
+
For each slug in missing_page_slugs:
|
|
104
|
+
1) Derive a filename by converting snake_case to camelCase and append ".cy.ts".
|
|
105
|
+
Example: file_upload_new -> fileUploadNew.cy.ts
|
|
106
|
+
2) Create {{inputs.test_dir}}/<filename> if it does not already exist.
|
|
107
|
+
3) Write generated_tests_map[<slug>] to the file.
|
|
108
|
+
Output: created_test_files.
|
|
@@ -82,8 +82,13 @@ export default {
|
|
|
82
82
|
<style lang="scss">
|
|
83
83
|
.v-btn {
|
|
84
84
|
&.link {
|
|
85
|
+
/* `height: inherit/auto/initial` will stretch to max height when used inside a horizontal panel,
|
|
86
|
+
presumably because it is affected by the panel's flex arrangement. */
|
|
87
|
+
height: 16px;
|
|
88
|
+
font-size: 1rem;
|
|
89
|
+
|
|
85
90
|
.v-icon {
|
|
86
|
-
font-size:
|
|
91
|
+
font-size: 1.2rem;
|
|
87
92
|
}
|
|
88
93
|
}
|
|
89
94
|
}
|
|
@@ -102,10 +107,6 @@ button {
|
|
|
102
107
|
/* text-decoration: underline; */
|
|
103
108
|
padding-left: 0;
|
|
104
109
|
padding-right: 0;
|
|
105
|
-
/* `height: inherit/auto/initial` will stretch to max height when used inside a horizontal panel,
|
|
106
|
-
presumably because it is affected by the panel's flex arrangement. */
|
|
107
|
-
height: 16px;
|
|
108
|
-
font-size: 16px;
|
|
109
110
|
line-height: 1;
|
|
110
111
|
min-width: auto;
|
|
111
112
|
box-shadow: none !important;
|
package/components/component.vue
CHANGED
|
@@ -68,7 +68,6 @@ import HiddenField from "./fields/hidden.vue";
|
|
|
68
68
|
import TextField from "./fields/text.vue";
|
|
69
69
|
import SubmitField from "./fields/submit.vue";
|
|
70
70
|
import TextAreaField from "./fields/textarea.vue";
|
|
71
|
-
const RichTextField = defineAsyncComponent(() => import("./fields/richText.vue"));
|
|
72
71
|
const RichTextField2 = defineAsyncComponent(() => import("./fields/richText2.vue"));
|
|
73
72
|
// import NewRichTextField from "./fields/newRichText.vue";
|
|
74
73
|
const FileField = defineAsyncComponent(() => import("./fields/file.vue"));
|
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
<!-- Set `menu-props` so the menu will never be wider than the select field.
|
|
4
4
|
See https://github.com/vuetifyjs/vuetify/issues/17751 -->
|
|
5
5
|
<component ref="comp" :is="compName" :color="gcolor" v-model="fieldModel" :label="label" :items="normalizedOptions"
|
|
6
|
-
:disabled="inputDisabled" :multiple="spec.multiple" :readonly="spec.readOnly"
|
|
7
|
-
:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@blur="focused = false" :menu-props="{ maxWidth: 0 }">
|
|
6
|
+
:disabled="inputDisabled" :multiple="spec.multiple" :readonly="spec.readOnly" :clearable="spec.clearable"
|
|
7
|
+
:placeholder="spec.placeholder" :rules="$validation()" persistent-hint :append-icon="append.icon"
|
|
8
|
+
validate-on="input" item-title='text' :variant="variant" :density="density" persistent-placeholder
|
|
9
|
+
@update:modelValue="onChange" @focus="focused = true" @blur="focused = false" :menu-props="{ maxWidth: 0 }">
|
|
11
10
|
|
|
12
11
|
<template #item="{ props, item }">
|
|
13
12
|
<div class="fields-select-option">
|
|
@@ -23,7 +22,7 @@
|
|
|
23
22
|
<select-item-default v-else :context="props" :item="item" :spec="spec"></select-item-default>
|
|
24
23
|
</div>
|
|
25
24
|
</template>
|
|
26
|
-
|
|
25
|
+
|
|
27
26
|
<template v-slot:prepend-item>
|
|
28
27
|
<template v-if="spec.prependSelectAll">
|
|
29
28
|
<v-list-item title="Select All" @click="checkAll">
|
|
@@ -40,35 +39,18 @@
|
|
|
40
39
|
</template>
|
|
41
40
|
|
|
42
41
|
<template v-if="useChips" #selection="{ item, index }">
|
|
43
|
-
<v-chip
|
|
44
|
-
v-if="index < maxVisibleChips"
|
|
45
|
-
:density="density"
|
|
46
|
-
closable
|
|
47
|
-
@click:close="removeItem(item)"
|
|
48
|
-
>
|
|
42
|
+
<v-chip v-if="index < maxVisibleChips" :density="density" closable @click:close="removeItem(item)">
|
|
49
43
|
<span>{{ item.title }}</span>
|
|
50
44
|
</v-chip>
|
|
51
45
|
<v-chip
|
|
52
46
|
v-if="!expanded && chipExceedsTwoLines && visibleChipCount < fieldModel.length && index === visibleChipCount"
|
|
53
|
-
:density="density"
|
|
54
|
-
|
|
55
|
-
@click="expanded = true"
|
|
56
|
-
class="text-caption expansion-chip"
|
|
57
|
-
variant="outlined"
|
|
58
|
-
color="primary"
|
|
59
|
-
>
|
|
47
|
+
:density="density" clickable @click="expanded = true" class="text-caption expansion-chip" variant="outlined"
|
|
48
|
+
color="primary">
|
|
60
49
|
{{ fieldModel.length - visibleChipCount }} more
|
|
61
50
|
<common-icon :spec="{ material: { name: 'expand_more' } }" class="ml-1" />
|
|
62
51
|
</v-chip>
|
|
63
|
-
<v-chip
|
|
64
|
-
|
|
65
|
-
:density="density"
|
|
66
|
-
clickable
|
|
67
|
-
@click="collapseChips"
|
|
68
|
-
class="text-caption expansion-chip"
|
|
69
|
-
variant="outlined"
|
|
70
|
-
color="primary"
|
|
71
|
-
>
|
|
52
|
+
<v-chip v-if="expanded && chipExceedsTwoLines && index === fieldModel.length - 1" :density="density" clickable
|
|
53
|
+
@click="collapseChips" class="text-caption expansion-chip" variant="outlined" color="primary">
|
|
72
54
|
Show less
|
|
73
55
|
<common-icon :spec="{ material: { name: 'expand_less' } }" class="ml-1" />
|
|
74
56
|
</v-chip>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
validation error on page load.
|
|
5
5
|
-->
|
|
6
6
|
<v-radio-group v-model="fieldModel" :name="fieldName" :readonly="spec.readOnly" :disabled="inputDisabled"
|
|
7
|
-
:rules="$validation()" :inline="spec.row" validate-on="
|
|
7
|
+
:rules="$validation()" :inline="spec.row" validate-on="input" @change="$executeOnChange()" :class="$classes()"
|
|
8
8
|
:style="$styles()" v-if="loadIf">
|
|
9
9
|
<!-- <div v-for="(childView, index) in spec.childViews" :key="index">
|
|
10
10
|
<glib-component :spec="childView" />
|
|
@@ -24,12 +24,24 @@ export default {
|
|
|
24
24
|
paddingBottom: null
|
|
25
25
|
};
|
|
26
26
|
},
|
|
27
|
+
watch: {
|
|
28
|
+
spec: {
|
|
29
|
+
deep: true,
|
|
30
|
+
handler() {
|
|
31
|
+
this.updateFromSpec();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
},
|
|
27
35
|
methods: {
|
|
28
36
|
$ready() {
|
|
37
|
+
this.updateFromSpec();
|
|
38
|
+
},
|
|
39
|
+
updateFromSpec() {
|
|
40
|
+
this.paddingBottom = null;
|
|
29
41
|
this.width = this.$length(this.spec.width);
|
|
30
42
|
this.height = this.$length(this.spec.height);
|
|
31
43
|
|
|
32
|
-
if (this.height
|
|
44
|
+
if (Utils.type.isNull(this.height)) {
|
|
33
45
|
// Let the container calculates the height
|
|
34
46
|
this.height = "100%";
|
|
35
47
|
|
|
@@ -230,15 +230,6 @@ const componentSpecOverrides: Record<string, Record<string, unknown>> = {
|
|
|
230
230
|
},
|
|
231
231
|
],
|
|
232
232
|
},
|
|
233
|
-
"panels-bulkEdit": {
|
|
234
|
-
sections: [
|
|
235
|
-
{
|
|
236
|
-
header: { dataCells: ["Header"] },
|
|
237
|
-
rows: [],
|
|
238
|
-
dataRows: [],
|
|
239
|
-
},
|
|
240
|
-
],
|
|
241
|
-
},
|
|
242
233
|
"panels-bulkEdit2": {
|
|
243
234
|
viewHeaders: [{ id: "col-1", text: "Header" }],
|
|
244
235
|
viewCells: [{ view: "fields/text", name: "col-1", label: "Header" }],
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { testPageUrl } from "../../helper"
|
|
2
|
+
|
|
3
|
+
const url = testPageUrl('browsers')
|
|
4
|
+
|
|
5
|
+
const stubCountryLookup = () => {
|
|
6
|
+
cy.intercept('GET', 'http://ip-api.com/json/', {
|
|
7
|
+
statusCode: 200,
|
|
8
|
+
body: {
|
|
9
|
+
country: 'Testland',
|
|
10
|
+
countryCode: 'TT'
|
|
11
|
+
}
|
|
12
|
+
}).as('ipLookup')
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
describe('browsers', () => {
|
|
16
|
+
it('detects timezone and posts form data', () => {
|
|
17
|
+
stubCountryLookup()
|
|
18
|
+
cy.visit(url)
|
|
19
|
+
|
|
20
|
+
cy.contains('button', 'browsers/detectTimezone').click()
|
|
21
|
+
|
|
22
|
+
cy.get('.v-dialog').should('contain.text', 'Method: POST')
|
|
23
|
+
cy.get('.v-dialog').should('contain.text', 'timezone')
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('detects country with form data and posts', () => {
|
|
27
|
+
stubCountryLookup()
|
|
28
|
+
cy.visit(url)
|
|
29
|
+
|
|
30
|
+
cy.contains('button', 'browsers/detectCountry (with formData)').click()
|
|
31
|
+
|
|
32
|
+
cy.get('.v-dialog').should('contain.text', 'Method: POST')
|
|
33
|
+
cy.get('.v-dialog').should('contain.text', 'message')
|
|
34
|
+
cy.get('.v-dialog').should('contain.text', 'country')
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('updates status after detectTimezone', () => {
|
|
38
|
+
stubCountryLookup()
|
|
39
|
+
cy.visit(url)
|
|
40
|
+
|
|
41
|
+
cy.contains('button', 'browsers/detectTimezone (update status)').click()
|
|
42
|
+
|
|
43
|
+
cy.contains('#browsers_status', 'Status: detected timezone').should('exist')
|
|
44
|
+
cy.contains('.v-snackbar', 'Timezone detected').should('exist')
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('alerts for detectCountry without form data', () => {
|
|
48
|
+
stubCountryLookup()
|
|
49
|
+
cy.visit(url)
|
|
50
|
+
|
|
51
|
+
cy.contains('button', 'browsers/detectCountry (no formData)').click()
|
|
52
|
+
|
|
53
|
+
cy.contains('.v-snackbar', 'Country detect requested').should('exist')
|
|
54
|
+
})
|
|
55
|
+
})
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { testPageUrl } from "../../helper"
|
|
2
|
+
|
|
3
|
+
const url = testPageUrl('calendar')
|
|
4
|
+
const sheetSelector = '#calendar_main .v-sheet'
|
|
5
|
+
|
|
6
|
+
const expectSheetHeight = (height) => {
|
|
7
|
+
cy.get(sheetSelector).should(($sheet) => {
|
|
8
|
+
expect($sheet[0].style.height).to.eq(height)
|
|
9
|
+
})
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const expectSheetWidth = (width) => {
|
|
13
|
+
cy.get(sheetSelector).should(($sheet) => {
|
|
14
|
+
expect($sheet[0].style.width).to.eq(width)
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe('calendar', () => {
|
|
19
|
+
it('resizes calendar with variant buttons', () => {
|
|
20
|
+
cy.visit(url)
|
|
21
|
+
|
|
22
|
+
cy.contains('button', 'Default size').click()
|
|
23
|
+
expectSheetHeight('420px')
|
|
24
|
+
|
|
25
|
+
cy.contains('button', 'Compact').click()
|
|
26
|
+
expectSheetHeight('320px')
|
|
27
|
+
|
|
28
|
+
cy.contains('button', 'Tall').click()
|
|
29
|
+
expectSheetHeight('560px')
|
|
30
|
+
|
|
31
|
+
cy.contains('button', 'Fixed width').click()
|
|
32
|
+
expectSheetWidth('720px')
|
|
33
|
+
})
|
|
34
|
+
})
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { testPageUrl } from "../../helper"
|
|
2
|
+
|
|
3
|
+
const url = testPageUrl('carousel')
|
|
4
|
+
|
|
5
|
+
describe('carousel', () => {
|
|
6
|
+
it('updates distribution buttons', () => {
|
|
7
|
+
cy.visit(url)
|
|
8
|
+
|
|
9
|
+
cy.contains('button', 'Fill equally').click()
|
|
10
|
+
cy.window().then((win) => {
|
|
11
|
+
const comp = win.GLib.component.findById('carousel_main')
|
|
12
|
+
expect(comp).to.exist
|
|
13
|
+
expect(comp.spec.distribution).to.eq('fillEqually')
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
cy.contains('button', 'Space equally').click()
|
|
17
|
+
cy.window().then((win) => {
|
|
18
|
+
const comp = win.GLib.component.findById('carousel_main')
|
|
19
|
+
expect(comp.spec.distribution).to.eq('spaceEqually')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
cy.contains('button', 'Clear distribution').click()
|
|
23
|
+
cy.window().then((win) => {
|
|
24
|
+
const comp = win.GLib.component.findById('carousel_main')
|
|
25
|
+
expect(comp.spec.distribution).to.eq(null)
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('updates action status from carousel items', () => {
|
|
30
|
+
cy.visit(url)
|
|
31
|
+
|
|
32
|
+
cy.contains('button', 'Pick A')
|
|
33
|
+
.closest('.v-carousel')
|
|
34
|
+
.as('actionCarousel')
|
|
35
|
+
|
|
36
|
+
cy.get('@actionCarousel').within(() => {
|
|
37
|
+
cy.contains('button', 'Pick A').click({ force: true })
|
|
38
|
+
})
|
|
39
|
+
cy.get('#carousel_action_status').should('contain.text', 'Action status: A')
|
|
40
|
+
|
|
41
|
+
cy.get('@actionCarousel').within(() => {
|
|
42
|
+
cy.get('.v-window__right').click({ force: true })
|
|
43
|
+
cy.contains('button', 'Pick B').click({ force: true })
|
|
44
|
+
})
|
|
45
|
+
cy.get('#carousel_action_status').should('contain.text', 'Action status: B')
|
|
46
|
+
|
|
47
|
+
cy.get('@actionCarousel').within(() => {
|
|
48
|
+
cy.get('.v-window__right').click({ force: true })
|
|
49
|
+
cy.contains('button', 'Pick C').click({ force: true })
|
|
50
|
+
})
|
|
51
|
+
cy.get('#carousel_action_status').should('contain.text', 'Action status: C')
|
|
52
|
+
})
|
|
53
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { testPageUrl } from "../../helper"
|
|
2
|
+
const url = testPageUrl('charts')
|
|
3
|
+
|
|
4
|
+
describe('charts', () => {
|
|
5
|
+
it('opens full charts demo', () => {
|
|
6
|
+
cy.visit(url)
|
|
7
|
+
|
|
8
|
+
cy.contains('h2', 'Charts').should('be.visible')
|
|
9
|
+
cy.get('#charts_preview').should('exist')
|
|
10
|
+
})
|
|
11
|
+
})
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { testPageUrl } from "../../helper"
|
|
2
|
+
|
|
3
|
+
const url = testPageUrl('column')
|
|
4
|
+
|
|
5
|
+
describe('column', () => {
|
|
6
|
+
it('shows snackbars for column size buttons', () => {
|
|
7
|
+
cy.visit(url)
|
|
8
|
+
|
|
9
|
+
cy.contains('button', '6 cols').click()
|
|
10
|
+
cy.get('.v-snackbar').should('contain.text', 'Not implemented yet!')
|
|
11
|
+
|
|
12
|
+
cy.contains('button', '4 cols').click()
|
|
13
|
+
cy.get('.v-snackbar').should('contain.text', 'Not implemented yet!')
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('updates column padding', () => {
|
|
17
|
+
cy.visit(url)
|
|
18
|
+
|
|
19
|
+
cy.contains('button', 'Add padding').click()
|
|
20
|
+
cy.get('#column_main')
|
|
21
|
+
.should('have.css', 'padding-top', '12px')
|
|
22
|
+
|
|
23
|
+
cy.contains('button', 'Clear padding').click()
|
|
24
|
+
cy.get('#column_main')
|
|
25
|
+
.should('not.have.css', 'padding-top', '12px')
|
|
26
|
+
})
|
|
27
|
+
})
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { testPageUrl } from "../../helper"
|
|
2
|
+
|
|
3
|
+
const url = testPageUrl('commands')
|
|
4
|
+
|
|
5
|
+
describe('commands', () => {
|
|
6
|
+
it('copies values to the clipboard', () => {
|
|
7
|
+
cy.visit(url)
|
|
8
|
+
|
|
9
|
+
cy.window().then((win) => {
|
|
10
|
+
cy.stub(win.navigator.clipboard, 'writeText')
|
|
11
|
+
.callsFake((text) => Promise.resolve(text))
|
|
12
|
+
.as('writeText')
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
cy.contains('button', 'commands/copy').click()
|
|
16
|
+
cy.get('@writeText').should('have.been.calledWith', 'Paste this somewhere else')
|
|
17
|
+
|
|
18
|
+
cy.contains('button', 'commands/copy (short)').click()
|
|
19
|
+
cy.get('@writeText').should('have.been.calledWith', 'Copied from commands test page')
|
|
20
|
+
|
|
21
|
+
cy.contains('button', 'commands/copy (long)').click()
|
|
22
|
+
cy.get('@writeText').should(
|
|
23
|
+
'have.been.calledWith',
|
|
24
|
+
'Long text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
cy.contains('button', 'commands/copy (with onCopy)').click()
|
|
28
|
+
cy.get('@writeText').should('have.been.calledWith', 'Copied with callback')
|
|
29
|
+
cy.get('#commands_status').should('contain.text', 'Status: copied')
|
|
30
|
+
cy.contains('.v-snackbar', 'Copied').should('exist')
|
|
31
|
+
|
|
32
|
+
cy.contains('button', 'commands/copy (multiline)').click()
|
|
33
|
+
cy.get('@writeText').should('have.been.calledWith', 'Line 1\nLine 2\nLine 3')
|
|
34
|
+
})
|
|
35
|
+
})
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { testPageUrl } from "../../helper"
|
|
2
|
+
|
|
3
|
+
const url = testPageUrl('components')
|
|
4
|
+
|
|
5
|
+
describe('components', () => {
|
|
6
|
+
it('updates label text with components/set', () => {
|
|
7
|
+
cy.visit(url)
|
|
8
|
+
|
|
9
|
+
cy.contains('button', 'components/set text').click()
|
|
10
|
+
|
|
11
|
+
cy.contains('#components_basic', 'Label text: updated').should('exist')
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
it('toggles visibility with components/set', () => {
|
|
15
|
+
cy.visit(url)
|
|
16
|
+
|
|
17
|
+
cy.contains('button', 'Hide').click()
|
|
18
|
+
cy.get('#components_basic').should('not.be.visible')
|
|
19
|
+
|
|
20
|
+
cy.contains('button', 'Show').click()
|
|
21
|
+
cy.get('#components_basic').should('be.visible')
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('fires onSet callbacks', () => {
|
|
25
|
+
cy.visit(url)
|
|
26
|
+
|
|
27
|
+
cy.contains('button', 'components/set (with onSet)').click()
|
|
28
|
+
|
|
29
|
+
cy.contains('#components_status', 'Status: set callback fired').should('exist')
|
|
30
|
+
cy.contains('.v-snackbar', 'Updated').should('exist')
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
// it('replaces components and restores label', () => {
|
|
34
|
+
// cy.visit(url)
|
|
35
|
+
|
|
36
|
+
// cy.contains('button', 'Replace with icon').click()
|
|
37
|
+
// cy.get('#components_replace_target', { timeout: 10000 })
|
|
38
|
+
// .should('have.class', 'v-icon')
|
|
39
|
+
// .and('contain.text', 'verified')
|
|
40
|
+
|
|
41
|
+
// cy.contains('button', 'Replace with button').click()
|
|
42
|
+
// cy.get('#components_replace_target', { timeout: 10000 })
|
|
43
|
+
// .should('contain.text', 'New button')
|
|
44
|
+
// .click()
|
|
45
|
+
// cy.contains('.v-snackbar', 'Button clicked').should('exist')
|
|
46
|
+
|
|
47
|
+
// cy.contains('button', 'Restore label').click()
|
|
48
|
+
// cy.contains('#components_replace_target', 'Replace me').should('exist')
|
|
49
|
+
// })
|
|
50
|
+
})
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { testPageUrl } from "../../helper"
|
|
2
|
+
|
|
3
|
+
const url = testPageUrl('custom')
|
|
4
|
+
|
|
5
|
+
describe('custom', () => {
|
|
6
|
+
it('switches custom data payloads', () => {
|
|
7
|
+
cy.visit(url)
|
|
8
|
+
|
|
9
|
+
cy.get('#custom_main').should('contain.text', 'Primary')
|
|
10
|
+
|
|
11
|
+
cy.contains('button', 'Alternate data').click()
|
|
12
|
+
cy.get('#custom_main').should('contain.text', 'Alternate')
|
|
13
|
+
|
|
14
|
+
cy.contains('button', 'Primary data').click()
|
|
15
|
+
cy.get('#custom_main').should('contain.text', 'Primary')
|
|
16
|
+
})
|
|
17
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { testPageUrl } from "../../helper"
|
|
2
|
+
const url = testPageUrl('dialog_open')
|
|
3
|
+
|
|
4
|
+
describe('dialog open', () => {
|
|
5
|
+
it('opens and closes dialog', () => {
|
|
6
|
+
cy.visit(url)
|
|
7
|
+
|
|
8
|
+
cy.contains('open').click()
|
|
9
|
+
cy.get('.v-dialog').should('exist')
|
|
10
|
+
|
|
11
|
+
cy.get('.v-dialog').contains('close').click()
|
|
12
|
+
cy.get('.v-dialog').should('not.exist')
|
|
13
|
+
})
|
|
14
|
+
})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { testPageUrl } from "../../helper"
|
|
2
|
+
const url = testPageUrl('file_upload_new')
|
|
3
|
+
|
|
4
|
+
describe('file upload new', () => {
|
|
5
|
+
it('renders upload fields', () => {
|
|
6
|
+
cy.visit(url)
|
|
7
|
+
|
|
8
|
+
cy.contains('Reset').click()
|
|
9
|
+
cy.contains('Field Upload').should('exist')
|
|
10
|
+
cy.get('input[type="file"]').should('exist')
|
|
11
|
+
})
|
|
12
|
+
})
|