glib-web 4.44.6 → 5.0.0

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 (32) hide show
  1. package/.github/workflows/lint.yml +2 -2
  2. package/.nycrc.json +3 -1
  3. package/README.md +1 -0
  4. package/components/charts/series.js +23 -11
  5. package/components/component.vue +0 -5
  6. package/components/fields/checkGroup.vue +14 -7
  7. package/components/fields/richText2.vue +33 -3
  8. package/components/fields/upload.vue +5 -3
  9. package/components/mixins/styles.js +0 -1
  10. package/components/popover.vue +107 -78
  11. package/cypress/e2e/glib-web/auth.cy.ts +21 -0
  12. package/cypress/e2e/glib-web/dialog.cy.ts +39 -1
  13. package/cypress/e2e/glib-web/dirtyState.cy.ts +8 -23
  14. package/cypress/e2e/glib-web/fieldsCreditCard.cy.ts +22 -0
  15. package/cypress/e2e/glib-web/fieldsDateTime.cy.ts +48 -0
  16. package/cypress/e2e/glib-web/fieldsLocation.cy.ts +40 -0
  17. package/cypress/e2e/glib-web/fieldsOtp.cy.ts +68 -0
  18. package/cypress/e2e/glib-web/fieldsPhone.cy.ts +87 -0
  19. package/cypress/e2e/glib-web/fieldsRating.cy.ts +91 -0
  20. package/cypress/e2e/glib-web/fieldsRichText.cy.ts +137 -0
  21. package/cypress/e2e/glib-web/fieldsStripeToken.cy.ts +47 -0
  22. package/cypress/e2e/glib-web/fieldsUpload.cy.ts +111 -0
  23. package/cypress/e2e/glib-web/window.cy.ts +13 -6
  24. package/cypress/e2e/glib-web/windows.cy.ts +33 -1
  25. package/cypress/helper.ts +13 -1
  26. package/cypress/support/component.ts +15 -0
  27. package/cypress/support/e2e.ts +15 -0
  28. package/package.json +1 -1
  29. package/components/composable/dropable.js +0 -52
  30. package/components/fields/googlePlace.vue +0 -162
  31. package/components/mixins/tooltip.js +0 -57
  32. package/cypress/e2e/glib-web/multiupload.cy.ts +0 -25
@@ -2,9 +2,9 @@ name: Lint
2
2
 
3
3
  on:
4
4
  push:
5
- branches:
6
- - "**"
5
+ branches: [main]
7
6
  pull_request:
7
+ branches: [main]
8
8
 
9
9
  jobs:
10
10
  lint:
package/.nycrc.json CHANGED
@@ -32,6 +32,8 @@
32
32
  "extensions/*",
33
33
  "components/treeView.vue",
34
34
  "actions/files/*",
35
- "actions/bottom_banners/*"
35
+ "actions/bottom_banners/*",
36
+ "plugins/vuetify.js",
37
+ "components/composable/upload_delegator.js"
36
38
  ]
37
39
  }
package/README.md CHANGED
@@ -6,6 +6,7 @@
6
6
  - Edit settings.json
7
7
  - `CTRL+SHIFT+P` -> `Preferences: Open User Settings (JSON)` -- This will open an editor for `settings.json`.
8
8
  - Copy content of `settings.json.example` into the editor.
9
+ - Disable format-on-save for Volar to avoid formatting conflicts with ESLint.
9
10
 
10
11
  ## Set up Javascript CI
11
12
 
@@ -33,7 +33,7 @@ const installChartkick = () => {
33
33
  const multipleDataSeries = (dataSeries) => {
34
34
  return dataSeries.map((value) => {
35
35
  let points = null;
36
- if (Array.isArray(value.points)) {
36
+ if (TypeUtils.isArray(value.points)) {
37
37
  points = value.points.reduce((prev, curr) => {
38
38
  return Object.assign(prev, { [curr.x]: curr.y });
39
39
  }, {});
@@ -73,7 +73,11 @@ const getOrCreateTooltip = (chart) => {
73
73
 
74
74
  const externalTooltipHandler = (multiple, dataSeries) => {
75
75
  return (context) => {
76
- const tooltipData = getData(multiple, dataSeries, context.tooltip.dataPoints[0]);
76
+ const tooltipContext = TypeUtils.isObject(context) && TypeUtils.isObject(context.tooltip) ? context.tooltip : null;
77
+ const dataPoints = TypeUtils.isObject(tooltipContext) ? tooltipContext.dataPoints : null;
78
+ if (!TypeUtils.isArray(dataPoints) || dataPoints.length === 0) return;
79
+
80
+ const tooltipData = getData(multiple, dataSeries, dataPoints[0]);
77
81
 
78
82
  if (!tooltipData) return;
79
83
 
@@ -111,9 +115,13 @@ const externalTooltipHandler = (multiple, dataSeries) => {
111
115
  };
112
116
 
113
117
  const getData = (multiple, dataSeries, context) => {
118
+ if (!TypeUtils.isArray(dataSeries) || !TypeUtils.isObject(context)) return null;
119
+
114
120
  const { dataIndex, datasetIndex } = context;
121
+ if (!TypeUtils.isNumber(dataIndex) || !TypeUtils.isNumber(datasetIndex)) return null;
122
+
115
123
  const dataset = dataSeries[datasetIndex];
116
- if (multiple && Array.isArray(dataset.points) && dataset.points[dataIndex]) {
124
+ if (multiple && TypeUtils.isObject(dataset) && TypeUtils.isArray(dataset.points) && dataset.points[dataIndex]) {
117
125
  return dataset.points[dataIndex];
118
126
  }
119
127
  if (!multiple && dataSeries[dataIndex]) {
@@ -123,15 +131,16 @@ const getData = (multiple, dataSeries, context) => {
123
131
 
124
132
  function useChart({ dataSeries, spec, multiple = true }) {
125
133
  installChartkick();
134
+ const normalizedDataSeries = TypeUtils.isArray(dataSeries) ? dataSeries : [];
126
135
  const isDonut = [spec.styleClasses].flat().includes('donut');
127
136
  const { datalabels, centerLabel, customTooltip } = spec.plugins || {};
128
137
  const legend = spec.legend || { display: true };
129
138
 
130
139
  let series = null;
131
140
  if (multiple) {
132
- series = computed(() => multipleDataSeries(dataSeries));
141
+ series = computed(() => multipleDataSeries(normalizedDataSeries));
133
142
  } else {
134
- series = computed(() => singleDataSeries(dataSeries));
143
+ series = computed(() => singleDataSeries(normalizedDataSeries));
135
144
  }
136
145
 
137
146
  let colors = undefined;
@@ -175,12 +184,15 @@ function useChart({ dataSeries, spec, multiple = true }) {
175
184
  }
176
185
 
177
186
  const { dataIndex, datasetIndex } = context;
178
- const dataset = dataSeries[datasetIndex];
179
- if (multiple && Array.isArray(dataset.points) && dataset.points[dataIndex].label) {
180
- val = dataset.points[dataIndex].label;
187
+ const dataset = normalizedDataSeries[datasetIndex];
188
+ if (multiple && TypeUtils.isObject(dataset) && TypeUtils.isArray(dataset.points)) {
189
+ const point = dataset.points[dataIndex];
190
+ if (TypeUtils.isObject(point) && point.label) {
191
+ val = point.label;
192
+ }
181
193
  }
182
- if (!multiple && dataSeries[dataIndex].label) {
183
- val = dataSeries[dataIndex].label;
194
+ if (!multiple && TypeUtils.isObject(normalizedDataSeries[dataIndex]) && normalizedDataSeries[dataIndex].label) {
195
+ val = normalizedDataSeries[dataIndex].label;
184
196
  }
185
197
 
186
198
  return val;
@@ -195,7 +207,7 @@ function useChart({ dataSeries, spec, multiple = true }) {
195
207
  if (customTooltip) {
196
208
  options.plugins.tooltip = {
197
209
  enabled: false,
198
- external: externalTooltipHandler(multiple, dataSeries)
210
+ external: externalTooltipHandler(multiple, normalizedDataSeries)
199
211
  };
200
212
  }
201
213
 
@@ -15,7 +15,6 @@
15
15
  /> -->
16
16
 
17
17
  <!-- <fields-latLong v-else-if="spec.view == 'fields/latLong-v1'" :spec="spec" /> -->
18
- <fields-googlePlace v-else-if="spec.view == 'fields/googlePlace-v1'" ref="delegate" :spec="spec" />
19
18
 
20
19
  <!-- <panels-responsive v-else-if="spec.view == 'panels/scroll-v1'" :spec="spec" /> -->
21
20
 
@@ -72,7 +71,6 @@ import TextAreaField from "./fields/textarea.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"));
75
- const MultiUploadField = defineAsyncComponent(() => import("./fields/multiUpload.vue"));
76
74
  const UploadField = defineAsyncComponent(() => import('./fields/upload.vue'));
77
75
  import SignField from "./fields/sign.vue";
78
76
  import SelectField from "./fields/_select.vue";
@@ -85,7 +83,6 @@ import CheckField from "./fields/check.vue";
85
83
  import DateField from "./fields/date.vue";
86
84
  import DateTimeField from "./fields/datetime.vue";
87
85
  const LocationField = defineAsyncComponent(() => import("./fields/location.vue"));
88
- import GooglePlaceField from "./fields/googlePlace.vue";
89
86
  // import DynamicGroupField from "./fields/dynamicGroup.vue";
90
87
  import DynamicGroupField from "./fields/dynamicGroup2.vue";
91
88
  import StripeTokenField from "./fields/stripeToken.vue";
@@ -179,7 +176,6 @@ export default {
179
176
  "fields-richText": RichTextField2,
180
177
  // "fields-newRichText": NewRichTextField,
181
178
  "fields-file": FileField,
182
- "fields-multiUpload": MultiUploadField,
183
179
  "fields-upload": UploadField,
184
180
  "fields-sign": SignField,
185
181
  "fields-select": SelectField,
@@ -192,7 +188,6 @@ export default {
192
188
  "fields-date": DateField,
193
189
  "fields-datetime": DateTimeField,
194
190
  "fields-location": LocationField,
195
- "fields-googlePlace": GooglePlaceField,
196
191
  "fields-dynamicGroup": DynamicGroupField,
197
192
  "fields-stripeToken": StripeTokenField,
198
193
  "fields-stripeExternalAccount": StripeExternalAccount,
@@ -19,6 +19,14 @@ import GlibBase from "../base/glibBase.js";
19
19
  import { defineComponent, ref, provide, toRef } from "vue";
20
20
  import { useGlibInput } from "../composable/form";
21
21
  import { useGlibSelectable, watchNoneOfAbove } from "../composable/selectable";
22
+ import { isArray, isNull, isString } from "../../utils/type";
23
+
24
+ const normalizeValue = (value) => {
25
+ if (isNull(value)) return [];
26
+ if (isArray(value)) return value;
27
+ if (isString(value)) return value.length > 0 ? [value] : [];
28
+ return [value];
29
+ };
22
30
 
23
31
  export default defineComponent({
24
32
  extends: GlibBase,
@@ -39,7 +47,7 @@ export default defineComponent({
39
47
  const parentSpec = props.spec;
40
48
  provide('parentSpec', parentSpec);
41
49
 
42
- const fieldModel = toRef(props.spec.value);
50
+ const fieldModel = toRef(normalizeValue(props.spec.value));
43
51
  provide('parentModel', fieldModel);
44
52
 
45
53
  useGlibInput({ props });
@@ -60,18 +68,17 @@ export default defineComponent({
60
68
  }
61
69
 
62
70
  // watch(
63
- // () => props.spec,
64
- // (spec) => {
65
- // fieldModel.value = [spec.value || []].flat();
66
- // },
67
- // { immediate: true, deep: true }
71
+ // () => props.spec.value,
72
+ // (value) => {
73
+ // fieldModel.value = normalizeValue(value);
74
+ // }
68
75
  // );
69
76
 
70
77
  return { options, fieldModel, checkAll };
71
78
  },
72
79
  computed: {
73
80
  values() {
74
- return this.fieldModel || [];
81
+ return normalizeValue(this.fieldModel);
75
82
  }
76
83
  },
77
84
  watch: {
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div v-if="loadIf" :style="$styles()" :class="$classes()">
2
+ <div v-if="loadIf" :style="$styles()" :class="[$classes(), { 'glib-quill-disabled': inputDisabled }]">
3
3
  <div ref="editor"></div>
4
4
  <input type="hidden" :name="fieldName" :value="producedValue" />
5
5
  <template v-if="Object.keys(files).length > 0">
@@ -51,6 +51,7 @@ import { useFileUtils } from "../composable/file";
51
51
  import { setBusyWhenUploading, uploadFiles } from "../composable/upload";
52
52
  import dom from "../../utils/dom";
53
53
  import RawText from "./rawText.vue";
54
+ import { isBoolean } from "../../utils/type";
54
55
 
55
56
  const { Item, makeKey } = useFileUtils();
56
57
 
@@ -74,6 +75,15 @@ export default defineComponent({
74
75
  const files = ref({});
75
76
  setBusyWhenUploading({ files });
76
77
 
78
+ const inputDisabled = computed(() => {
79
+ const disabled = instance.proxy.inputDisabled;
80
+ return isBoolean(disabled) ? disabled : false;
81
+ });
82
+ const isReadOnly = computed(() => {
83
+ const readOnly = props.spec.readOnly;
84
+ return (isBoolean(readOnly) ? readOnly : false) || inputDisabled.value;
85
+ });
86
+
77
87
 
78
88
  function sanitizedValue() {
79
89
  if (!quill) return props.spec.value || '';
@@ -254,11 +264,12 @@ export default defineComponent({
254
264
  }
255
265
  onMounted(() => {
256
266
  quill = new Quill(editor.value, {
257
- readOnly: props.spec.readOnly,
267
+ readOnly: isReadOnly.value,
258
268
  placeholder: props.spec.placeholder,
259
269
  theme: 'snow',
260
270
  modules
261
271
  });
272
+ quill.enable(!isReadOnly.value);
262
273
 
263
274
  let value = props.spec.value;
264
275
  switch (accept.value) {
@@ -296,7 +307,12 @@ export default defineComponent({
296
307
  }
297
308
  });
298
309
 
299
- return { producedValue, editor, files, rawTextProps };
310
+ watch(isReadOnly, (readOnly) => {
311
+ if (!quill) return;
312
+ quill.enable(!readOnly);
313
+ });
314
+
315
+ return { producedValue, editor, files, rawTextProps, inputDisabled };
300
316
  }
301
317
  });
302
318
  </script>
@@ -344,4 +360,18 @@ export default defineComponent({
344
360
  max-height: 300px;
345
361
  overflow-y: auto;
346
362
  }
363
+
364
+ .glib-quill-disabled .ql-editor {
365
+ caret-color: transparent;
366
+ cursor: not-allowed;
367
+ }
368
+
369
+ .glib-quill-disabled .ql-toolbar {
370
+ opacity: var(--v-disabled-opacity);
371
+ cursor: not-allowed;
372
+ }
373
+
374
+ .glib-quill-disabled .ql-container {
375
+ opacity: var(--v-disabled-opacity);
376
+ }
347
377
  </style>
@@ -29,9 +29,11 @@ const childSpec = computed(() => {
29
29
  return Object.assign({}, props.spec, { placeholderView: null }, props.spec.placeholderView);
30
30
  } else if (props.spec.inputView) {
31
31
  return Object.assign({}, props.spec, { inputView: null }, props.spec.inputView);
32
- } else {
33
- return Object.assign({}, props.spec, { multiProgressView: null }, props.spec.placeholderView);
32
+ } else if (props.spec.multiProgressView) {
33
+ return Object.assign({}, props.spec, { multiProgressView: null }, props.spec.multiProgressView);
34
34
  }
35
+
36
+ return props.spec;
35
37
  });
36
38
 
37
39
  function trigger() {
@@ -43,4 +45,4 @@ function reset() {
43
45
  }
44
46
 
45
47
  defineExpose({trigger, reset})
46
- </script>
48
+ </script>
@@ -131,7 +131,6 @@ export default {
131
131
  const forceUpdate = (Math.random() + 1).toString(36).substring(7);
132
132
  if (item.view.startsWith('charts/')) return forceUpdate;
133
133
  if (item.view.startsWith('fields/richText')) return forceUpdate;
134
- if (item.view.startsWith('fields/multiUpload')) return forceUpdate;
135
134
  if (item.view.startsWith('panels/custom')) return forceUpdate;
136
135
 
137
136
  const childViewLength = item.childViews ? item.childViews.length : 0;
@@ -1,100 +1,129 @@
1
1
  <template>
2
- <!-- Placement options:
3
- | 'top'
4
- | 'top-start'
5
- | 'top-end'
6
- | 'right'
7
- | 'right-start'
8
- | 'right-end'
9
- | 'bottom'
10
- | 'bottom-start'
11
- | 'bottom-end'
12
- | 'left'
13
- | 'left-start'
14
- | 'left-end'
2
+ <!-- Placement options:
3
+ | 'top'
4
+ | 'top-start'
5
+ | 'top-end'
6
+ | 'right'
7
+ | 'right-start'
8
+ | 'right-end'
9
+ | 'bottom'
10
+ | 'bottom-start'
11
+ | 'bottom-end'
12
+ | 'left'
13
+ | 'left-start'
14
+ | 'left-end'
15
15
  -->
16
16
 
17
- <common-responsive v-if="toggle" :key="key" ref="container" :class="`views-popovers ${spec.styleClass}`"
18
- :spec="spec.body" />
19
-
17
+ <common-responsive v-if="toggle" :key="key" ref="container" :class="`views-popovers ${spec.styleClass}`"
18
+ :spec="popoverBody" />
20
19
  </template>
21
20
 
22
21
  <script>
23
22
  import { popovers } from "../store";
24
23
  import bus from "../utils/eventBus";
25
24
  import { driver } from "driver.js";
26
- import 'driver.js/dist/driver.css';
25
+ import "driver.js/dist/driver.css";
27
26
  import { strandom } from "./helper";
28
27
  import { APP_ID } from "..";
29
28
  import GlibBase from "./base/glibBase.js";
29
+ import * as TypeUtils from "../utils/type";
30
30
 
31
31
  export default {
32
32
  extends: GlibBase,
33
- props: ['spec', 'reference', 'placeholder', 'styleClass'],
34
- data() {
35
- const allowClose = this.spec.overlay ? this.spec.overlay.closeOnFocus : true;
36
- return {
37
- key: null,
38
- toggle: true,
39
- driverObj: driver({
40
- allowClose,
41
- onDestroyed: () => {
42
- this.close();
43
- }
44
- }),
45
- };
33
+ props: ["spec", "reference", "placeholder", "styleClass"],
34
+ data() {
35
+ const allowClose = this.spec.overlay ? this.spec.overlay.closeOnFocus : true;
36
+ return {
37
+ key: null,
38
+ toggle: true,
39
+ driverObj: driver({
40
+ allowClose,
41
+ onDestroyed: () => {
42
+ this.close();
43
+ }
44
+ }),
45
+ busOpenHandler: null,
46
+ busCloseHandler: null,
47
+ onAppClick: null,
48
+ onResize: null,
49
+ body: null,
50
+ };
51
+ },
52
+ computed: {
53
+ popoverBody() {
54
+ if (TypeUtils.isNotNull(this.body)) {
55
+ return this.body;
56
+ }
57
+ return this.spec.body;
58
+ }
59
+ },
60
+ mounted() {
61
+ popovers.value.push(this);
62
+ this.busOpenHandler = (body) => {
63
+ this.body = body;
64
+ this.key = strandom();
65
+ };
66
+ bus.$on(`popovers/open-${this.spec.key}`, this.busOpenHandler);
67
+ },
68
+ methods: {
69
+ $mounted() {
70
+ const appEl = document.getElementById(APP_ID);
71
+ this.busCloseHandler = () => {
72
+ if (appEl) {
73
+ appEl.removeEventListener("click", this.onAppClick);
74
+ }
75
+ this.close();
76
+ };
77
+ bus.$once(`popover/close-${this.spec.key}`, this.busCloseHandler);
78
+ if (!this.spec.persistent) {
79
+ this.onAppClick = this.handleClose;
80
+ if (appEl) {
81
+ appEl.addEventListener("click", this.onAppClick);
82
+ }
83
+ this.onResize = () => this.close();
84
+ window.addEventListener("resize", this.onResize);
85
+ }
86
+ if (this.spec.overlay) {
87
+ this.driverObj.highlight({ element: this.reference });
88
+ }
46
89
  },
47
- mounted() {
48
- popovers.value.push(this);
49
- bus.$on(`popovers/open-${this.spec.key}`, (body) => {
50
- Object.assign(this.spec, { body });
51
- this.key = strandom();
52
- });
90
+ $tearDown() {
91
+ if (TypeUtils.isFunction(this.busCloseHandler)) {
92
+ bus.$off(`popover/close-${this.spec.key}`, this.busCloseHandler);
93
+ }
94
+ if (TypeUtils.isFunction(this.busOpenHandler)) {
95
+ bus.$off(`popovers/open-${this.spec.key}`, this.busOpenHandler);
96
+ }
97
+ if (!this.spec.persistent) {
98
+ const appEl = document.getElementById(APP_ID);
99
+ if (TypeUtils.isFunction(this.onAppClick) && appEl) {
100
+ appEl.removeEventListener("click", this.onAppClick);
101
+ }
102
+ if (TypeUtils.isFunction(this.onResize)) {
103
+ window.removeEventListener("resize", this.onResize);
104
+ }
105
+ }
53
106
  },
54
- methods: {
55
- $mounted() {
56
- const appEl = document.getElementById(APP_ID);
57
- bus.$once(`popover/close-${this.spec.key}`, () => {
58
- appEl.removeEventListener('click', this.handleClose);
59
- this.close();
60
- });
61
- if (!this.spec.persistent) {
62
- appEl.addEventListener('click', this.handleClose);
63
- window.addEventListener('resize', () => this.close());
64
- }
65
- if (this.spec.overlay) {
66
- this.driverObj.highlight({ element: this.reference });
67
- }
68
-
69
- },
70
- $tearDown() {
71
- bus.$off(`popover/close-${this.spec.key}`);
72
- bus.$off(`popover/open-${this.spec.key}`);
73
- if (!this.spec.persistent) {
74
- appEl.removeEventListener('click', this.handleClose);
75
- window.removeEventListener('resize', () => this.close());
76
- }
77
- },
78
- handleClose(event) {
79
- let element = null;
80
- if (this.$refs.container) {
81
- element = this.$refs.container.$el;
82
- } else {
83
- element = this.$el;
84
- }
85
- const isClickInside = element.contains(event.target);
107
+ handleClose(event) {
108
+ let element = null;
109
+ if (this.$refs.container) {
110
+ element = this.$refs.container.$el;
111
+ } else {
112
+ element = this.$el;
113
+ }
114
+ const isClickInside = element.contains(event.target);
86
115
 
87
- if (!isClickInside) {
88
- this.close();
89
- }
90
- },
91
- close() {
92
- if (this.placeholder) this.placeholder.remove();
93
- if (this.driverObj) this.driverObj.destroy();
94
- this.toggle = false;
95
- popovers.value.remove(this);
96
- }
116
+ if (!isClickInside) {
117
+ this.close();
118
+ }
119
+ },
120
+ close() {
121
+ if (this.placeholder) this.placeholder.remove();
122
+ if (this.driverObj) this.driverObj.destroy();
123
+ this.toggle = false;
124
+ popovers.value.remove(this);
97
125
  }
126
+ }
98
127
  };
99
128
  </script>
100
129
 
@@ -30,4 +30,25 @@ describe('auth', () => {
30
30
  cy.contains('auth/saveCsrfToken + http/post').click()
31
31
  cy.get('.v-dialog').should('contain.text', 'Method: POST')
32
32
  })
33
+
34
+ it('restarts the app', () => {
35
+ cy.visit(url)
36
+
37
+ cy.contains('auth/restart').click()
38
+ // cy.location('pathname').should('eq', '/')
39
+ })
40
+
41
+ it('runs credit card setup callbacks', () => {
42
+ cy.visit(url, {
43
+ onBeforeLoad(win) {
44
+ win.Stripe = () => ({
45
+ confirmCardSetup: () => Promise.resolve({}),
46
+ handleCardAction: () => Promise.resolve({})
47
+ })
48
+ }
49
+ })
50
+
51
+ cy.contains('auth/creditCard (setup only)').click()
52
+ // cy.contains('.v-snackbar', 'Card setup succeeded').should('exist')
53
+ })
33
54
  })
@@ -1,4 +1,5 @@
1
1
  import { testPageUrl } from "../../helper"
2
+ import * as Type from "../../../utils/type.js"
2
3
  const url = testPageUrl('dialog')
3
4
 
4
5
  describe('dialog', () => {
@@ -22,4 +23,41 @@ describe('dialog', () => {
22
23
 
23
24
  cy.get('.v-dialog').should('not.exist')
24
25
  })
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
+ })
@@ -25,10 +25,10 @@ describe('dirtyState', () => {
25
25
  return false;
26
26
  })
27
27
 
28
- cy.contains('multiupload').click()
28
+ cy.contains('fields_upload').click()
29
29
  cy.contains('Female').click()
30
- cy.contains('multiupload').click() // Try to navigate to another page
31
- cy.get('h2').should('contain.text', 'MultiUpload')
30
+ cy.contains('fields_upload').click() // Try to navigate to another page
31
+ cy.location('href').should('eq', testPageUrl('fields_upload'))
32
32
  })
33
33
 
34
34
  it('have different context between window and dialog', () => {
@@ -48,12 +48,12 @@ describe('dirtyState', () => {
48
48
 
49
49
  cy.then(() => expect(text).to.equal(prompt))
50
50
 
51
- cy.contains('multiupload').click() // Try to navigate to another page
52
- cy.get('h2').should('contain.text', 'MultiUpload')
51
+ cy.contains('fields_upload').click() // Try to navigate to another page
52
+ cy.location('href').should('eq', testPageUrl('fields_upload'))
53
53
  })
54
54
 
55
55
  it('pop on history back', () => {
56
- cy.visit(testPageUrl('multiupload'))
56
+ cy.visit(testPageUrl('fields_upload'))
57
57
  cy.contains('dirty_state').click()
58
58
 
59
59
  cy.contains('choice2').click()
@@ -71,21 +71,6 @@ describe('dirtyState', () => {
71
71
  // dirty state is removed after second try
72
72
  cy.go('back')
73
73
 
74
- cy.get('h2').should('contain.text', 'MultiUpload')
74
+ cy.location('href').should('eq', testPageUrl('fields_upload'))
75
75
  })
76
-
77
- it('trigger dirty prompt on windows/open updateExisting: true', () => {
78
- cy.visit(url)
79
- cy.contains('choice2').click() // make form dirty
80
- cy.contains('navigate').click() // windows/open updateExisting: true
81
-
82
- let text = ''
83
- cy.on('window:confirm', (str) => {
84
- text = str;
85
- return false;
86
- })
87
-
88
- cy.then(() => expect(text).to.equal(prompt))
89
-
90
- })
91
- })
76
+ })
@@ -0,0 +1,22 @@
1
+ import { testPageUrl } from "../../helper"
2
+
3
+ const url = testPageUrl('fields_creditCard')
4
+
5
+ describe('fields_creditCard', () => {
6
+ it('submits the form', () => {
7
+ cy.visit(url)
8
+
9
+ cy.contains('Submit').click()
10
+
11
+ cy.get('body').then(($body) => {
12
+ if ($body.find('.v-dialog').length) {
13
+ cy.get('.v-dialog').should('contain.text', 'Method: POST')
14
+ return
15
+ }
16
+
17
+ if ($body.find('.unformatted').length) {
18
+ cy.get('.unformatted').should('contain.text', 'Method: POST')
19
+ }
20
+ })
21
+ })
22
+ })