@ionic/core 7.5.6-dev.11700169088.140f3e6a → 7.5.6-dev.11700492285.1581ed02

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 (68) hide show
  1. package/dist/collection/collection-manifest.json +4 -4
  2. package/dist/collection/components/accordion/test/accordion.spec.js +195 -0
  3. package/dist/collection/components/action-sheet/test/action-sheet-id.spec.js +32 -0
  4. package/dist/collection/components/action-sheet/test/basic/action-sheet.spec.js +18 -0
  5. package/dist/collection/components/alert/test/alert-id.spec.js +32 -0
  6. package/dist/collection/components/alert/test/alert.spec.js +37 -0
  7. package/dist/collection/components/back-button/test/back-button.spec.js +86 -0
  8. package/dist/collection/components/breadcrumb/test/aria.spec.js +22 -0
  9. package/dist/collection/components/breadcrumbs/test/breadcrumbs.spec.js +58 -0
  10. package/dist/collection/components/button/test/form-reference/button.spec.js +26 -0
  11. package/dist/collection/components/card/test/aria.spec.js +16 -0
  12. package/dist/collection/components/checkbox/test/checkbox.spec.js +20 -0
  13. package/dist/collection/components/datetime/test/a11y/datetime.spec.js +43 -0
  14. package/dist/collection/components/datetime/test/comparison.spec.js +43 -0
  15. package/dist/collection/components/datetime/test/data.spec.js +456 -0
  16. package/dist/collection/components/datetime/test/format.spec.js +124 -0
  17. package/dist/collection/components/datetime/test/helpers.spec.js +72 -0
  18. package/dist/collection/components/datetime/test/manipulation.spec.js +433 -0
  19. package/dist/collection/components/datetime/test/parse.spec.js +222 -0
  20. package/dist/collection/components/datetime/test/state.spec.js +114 -0
  21. package/dist/collection/components/infinite-scroll-content/test/infinite-scroll-content.spec.js +37 -0
  22. package/dist/collection/components/input/test/input.spec.js +85 -0
  23. package/dist/collection/components/input/test/item/input.spec.js +24 -0
  24. package/dist/collection/components/item/test/a11y/item.spec.js +48 -0
  25. package/dist/collection/components/loading/test/basic/loading.spec.js +16 -0
  26. package/dist/collection/components/loading/test/loading-id.spec.js +32 -0
  27. package/dist/collection/components/loading/test/loading.spec.js +37 -0
  28. package/dist/collection/components/modal/test/a11y/modal.spec.js +22 -0
  29. package/dist/collection/components/modal/test/basic/modal.spec.js +16 -0
  30. package/dist/collection/components/modal/test/can-dismiss/modal.spec.js +191 -0
  31. package/dist/collection/components/modal/test/modal-id.spec.js +32 -0
  32. package/dist/collection/components/nav/test/nav-controller.spec.js +749 -0
  33. package/dist/collection/components/picker/test/picker-id.spec.js +32 -0
  34. package/dist/collection/components/picker-column/test/picker-column-aria.spec.js +35 -0
  35. package/dist/collection/components/picker-column/test/picker-column-dynamic.spec.js +29 -0
  36. package/dist/collection/components/picker-column/test/picker-column.spec.js +17 -0
  37. package/dist/collection/components/popover/test/basic/popover.spec.js +16 -0
  38. package/dist/collection/components/popover/test/popover-id.spec.js +32 -0
  39. package/dist/collection/components/popover/test/util.spec.js +53 -0
  40. package/dist/collection/components/radio/test/radio.spec.js +46 -0
  41. package/dist/collection/components/range/test/label/range.spec.js +23 -0
  42. package/dist/collection/components/range/test/range.spec.js +205 -0
  43. package/dist/collection/components/refresher-content/test/refresher-content.spec.js +46 -0
  44. package/dist/collection/components/router/test/matching.spec.js +250 -0
  45. package/dist/collection/components/router/test/parser.spec.js +133 -0
  46. package/dist/collection/components/router/test/path.spec.js +218 -0
  47. package/dist/collection/components/router/test/router.spec.js +55 -0
  48. package/dist/collection/components/searchbar/test/searchbar.spec.js +15 -0
  49. package/dist/collection/components/segment/test/segment.spec.js +37 -0
  50. package/dist/collection/components/select/test/select.spec.js +59 -0
  51. package/dist/collection/components/textarea/test/textarea.spec.js +59 -0
  52. package/dist/collection/components/toast/test/toast-id.spec.js +32 -0
  53. package/dist/collection/components/toast/test/toast.spec.js +120 -0
  54. package/dist/collection/components/toggle/test/toggle.spec.js +55 -0
  55. package/dist/collection/global/test/config-controller.spec.js +77 -0
  56. package/dist/collection/utils/animation/test/animation.spec.js +431 -0
  57. package/dist/collection/utils/keyboard/test/keyboard-controller.spec.js +21 -0
  58. package/dist/collection/utils/keyboard/test/keyboard.spec.js +214 -0
  59. package/dist/collection/utils/sanitization/test/sanitization.spec.js +43 -0
  60. package/dist/collection/utils/test/aria.spec.js +79 -0
  61. package/dist/collection/utils/test/attributes.spec.js +53 -0
  62. package/dist/collection/utils/test/hardware-back-button.spec.js +53 -0
  63. package/dist/collection/utils/test/overlays/overlays.spec.js +102 -0
  64. package/dist/collection/utils/test/platform.spec.js +132 -0
  65. package/dist/collection/utils/test/ready.spec.js +39 -0
  66. package/dist/collection/utils/test/theme.spec.js +56 -0
  67. package/dist/docs.json +21 -21
  68. package/package.json +2 -1
@@ -0,0 +1,114 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { getCalendarDayState, isDayDisabled, isNextMonthDisabled, isPrevMonthDisabled } from "../utils/state";
5
+ describe('getCalendarDayState()', () => {
6
+ it('should return correct state', () => {
7
+ const refA = { month: 1, day: 1, year: 2019 };
8
+ const refB = { month: 1, day: 1, year: 2021 };
9
+ const refC = { month: 1, day: 1, year: 2023 };
10
+ expect(getCalendarDayState('en-US', refA, refB, refC)).toEqual({
11
+ isActive: false,
12
+ isToday: false,
13
+ disabled: false,
14
+ ariaSelected: null,
15
+ ariaLabel: 'Tuesday, January 1',
16
+ text: '1',
17
+ });
18
+ expect(getCalendarDayState('en-US', refA, refA, refC)).toEqual({
19
+ isActive: true,
20
+ isToday: false,
21
+ disabled: false,
22
+ ariaSelected: 'true',
23
+ ariaLabel: 'Tuesday, January 1',
24
+ text: '1',
25
+ });
26
+ expect(getCalendarDayState('en-US', refA, refB, refA)).toEqual({
27
+ isActive: false,
28
+ isToday: true,
29
+ disabled: false,
30
+ ariaSelected: null,
31
+ ariaLabel: 'Today, Tuesday, January 1',
32
+ text: '1',
33
+ });
34
+ expect(getCalendarDayState('en-US', refA, refA, refA)).toEqual({
35
+ isActive: true,
36
+ isToday: true,
37
+ disabled: false,
38
+ ariaSelected: 'true',
39
+ ariaLabel: 'Today, Tuesday, January 1',
40
+ text: '1',
41
+ });
42
+ expect(getCalendarDayState('en-US', refA, refA, refA, undefined, undefined, [1])).toEqual({
43
+ isActive: true,
44
+ isToday: true,
45
+ disabled: false,
46
+ ariaSelected: 'true',
47
+ ariaLabel: 'Today, Tuesday, January 1',
48
+ text: '1',
49
+ });
50
+ expect(getCalendarDayState('en-US', refA, refA, refA, undefined, undefined, [2])).toEqual({
51
+ isActive: true,
52
+ isToday: true,
53
+ disabled: true,
54
+ ariaSelected: 'true',
55
+ ariaLabel: 'Today, Tuesday, January 1',
56
+ text: '1',
57
+ });
58
+ });
59
+ });
60
+ describe('isDayDisabled()', () => {
61
+ it('should correctly return whether or not a day is disabled', () => {
62
+ const refDate = { month: 5, day: 12, year: 2021 };
63
+ expect(isDayDisabled(refDate, undefined, undefined)).toEqual(false);
64
+ expect(isDayDisabled(refDate, { month: 5, day: 12, year: 2021 }, undefined)).toEqual(false);
65
+ expect(isDayDisabled(refDate, { month: 6, day: 12, year: 2021 }, undefined)).toEqual(true);
66
+ expect(isDayDisabled(refDate, { month: 5, day: 13, year: 2022 }, undefined)).toEqual(true);
67
+ expect(isDayDisabled(refDate, undefined, { month: 5, day: 12, year: 2021 })).toEqual(false);
68
+ expect(isDayDisabled(refDate, undefined, { month: 4, day: 12, year: 2021 })).toEqual(true);
69
+ expect(isDayDisabled(refDate, undefined, { month: 5, day: 11, year: 2021 })).toEqual(true);
70
+ });
71
+ });
72
+ describe('isPrevMonthDisabled()', () => {
73
+ it('should return true', () => {
74
+ // Date month is before min month, in the same year
75
+ expect(isPrevMonthDisabled({ month: 5, year: 2021, day: null }, { month: 6, year: 2021, day: null })).toEqual(true);
76
+ // Date month and year is the same as min month and year
77
+ expect(isPrevMonthDisabled({ month: 1, year: 2021, day: null }, { month: 1, year: 2021, day: null })).toEqual(true);
78
+ // Date year is the same as min year (month not provided)
79
+ expect(isPrevMonthDisabled({ month: 1, year: 2021, day: null }, { year: 2021, month: null, day: null })).toEqual(true);
80
+ // Date year is less than the min year (month not provided)
81
+ expect(isPrevMonthDisabled({ month: 5, year: 2021, day: null }, { year: 2022, month: null, day: null })).toEqual(true);
82
+ // Date is above the maximum bounds and the previous month does not does not fall within the
83
+ // min-max range.
84
+ expect(isPrevMonthDisabled({ month: 12, year: 2021, day: null }, { month: 9, year: 2021, day: null }, { month: 10, year: 2021, day: null })).toEqual(true);
85
+ // Date is above the maximum bounds and a year ahead of the max range. The previous month/year
86
+ // does not fall within the min-max range.
87
+ expect(isPrevMonthDisabled({ month: 1, year: 2022, day: null }, { month: 9, year: 2021, day: null }, { month: 10, year: 2021, day: null })).toEqual(true);
88
+ });
89
+ it('should return false', () => {
90
+ // No min range provided
91
+ expect(isPrevMonthDisabled({ month: 12, year: 2021, day: null })).toEqual(false);
92
+ // Date year is the same as min year,
93
+ // but can navigate to a previous month without reducing the year.
94
+ expect(isPrevMonthDisabled({ month: 12, year: 2021, day: null }, { year: 2021, month: null, day: null })).toEqual(false);
95
+ expect(isPrevMonthDisabled({ month: 2, year: 2021, day: null }, { year: 2021, month: null, day: null })).toEqual(false);
96
+ });
97
+ });
98
+ describe('isNextMonthDisabled()', () => {
99
+ it('should return true', () => {
100
+ // Date month is the same as max month (in the same year)
101
+ expect(isNextMonthDisabled({ month: 10, year: 2021, day: null }, { month: 10, year: 2021, day: null })).toEqual(true);
102
+ // Date month is after the max month (in the same year)
103
+ expect(isNextMonthDisabled({ month: 10, year: 2021, day: null }, { month: 9, year: 2021, day: null })).toEqual(true);
104
+ // Date year is after the max month and year
105
+ expect(isNextMonthDisabled({ month: 10, year: 2022, day: null }, { month: 12, year: 2021, day: null })).toEqual(true);
106
+ });
107
+ it('should return false', () => {
108
+ // No max range provided
109
+ expect(isNextMonthDisabled({ month: 10, year: 2021, day: null })).toBe(false);
110
+ // Date month is before max month and is the previous month,
111
+ // so that navigating the next month would re-enter the max range
112
+ expect(isNextMonthDisabled({ month: 10, year: 2021, day: null }, { month: 11, year: 2021, day: null })).toEqual(false);
113
+ });
114
+ });
@@ -0,0 +1,37 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { newSpecPage } from "@stencil/core/testing";
5
+ import { config } from "../../../global/config";
6
+ import { InfiniteScrollContent } from "../infinite-scroll-content";
7
+ describe('infinite-scroll-content: custom html', () => {
8
+ it('should not allow for custom html by default', async () => {
9
+ const page = await newSpecPage({
10
+ components: [InfiniteScrollContent],
11
+ html: `<ion-infinite-scroll-content loading-text="<button class='custom-html'>Custom Text</button>"></ion-infinite-scroll-content>`,
12
+ });
13
+ const content = page.body.querySelector('.infinite-loading-text');
14
+ expect(content.textContent).toContain('Custom Text');
15
+ expect(content.querySelector('button.custom-html')).toBe(null);
16
+ });
17
+ it('should allow for custom html', async () => {
18
+ config.reset({ innerHTMLTemplatesEnabled: true });
19
+ const page = await newSpecPage({
20
+ components: [InfiniteScrollContent],
21
+ html: `<ion-infinite-scroll-content loading-text="<button class='custom-html'>Custom Text</button>"></ion-infinite-scroll-content>`,
22
+ });
23
+ const content = page.body.querySelector('.infinite-loading-text');
24
+ expect(content.textContent).toContain('Custom Text');
25
+ expect(content.querySelector('button.custom-html')).not.toBe(null);
26
+ });
27
+ it('should not allow for custom html', async () => {
28
+ config.reset({ innerHTMLTemplatesEnabled: false });
29
+ const page = await newSpecPage({
30
+ components: [InfiniteScrollContent],
31
+ html: `<ion-infinite-scroll-content loading-text="<button class='custom-html'>Custom Text2</button>"></ion-infinite-scroll-content>`,
32
+ });
33
+ const content = page.body.querySelector('.infinite-loading-text');
34
+ expect(content.textContent).toContain('Custom Text');
35
+ expect(content.querySelector('button.custom-html')).toBe(null);
36
+ });
37
+ });
@@ -0,0 +1,85 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { newSpecPage } from "@stencil/core/testing";
5
+ import { Input } from "../input";
6
+ describe('input: rendering', () => {
7
+ it('should inherit attributes', async () => {
8
+ const page = await newSpecPage({
9
+ components: [Input],
10
+ html: '<ion-input title="my title" tabindex="-1" data-form-type="password"></ion-input>',
11
+ });
12
+ const nativeEl = page.body.querySelector('ion-input input');
13
+ expect(nativeEl.getAttribute('title')).toBe('my title');
14
+ expect(nativeEl.getAttribute('tabindex')).toBe('-1');
15
+ expect(nativeEl.getAttribute('data-form-type')).toBe('password');
16
+ });
17
+ it('should render bottom content when helper text is defined', async () => {
18
+ const page = await newSpecPage({
19
+ components: [Input],
20
+ html: `<ion-input label="Input" helper-text="Helper Text"></ion-input>`,
21
+ });
22
+ const bottomContent = page.body.querySelector('ion-input .input-bottom');
23
+ expect(bottomContent).not.toBe(null);
24
+ });
25
+ it('should render bottom content when helper text is undefined', async () => {
26
+ const page = await newSpecPage({
27
+ components: [Input],
28
+ html: `<ion-input label="Input"></ion-input>`,
29
+ });
30
+ const bottomContent = page.body.querySelector('ion-input .input-bottom');
31
+ expect(bottomContent).toBe(null);
32
+ });
33
+ it('should render bottom content when helper text is empty string', async () => {
34
+ const page = await newSpecPage({
35
+ components: [Input],
36
+ html: `<ion-input label="Input" helper-text=""></ion-input>`,
37
+ });
38
+ const bottomContent = page.body.querySelector('ion-input .input-bottom');
39
+ expect(bottomContent).toBe(null);
40
+ });
41
+ });
42
+ /**
43
+ * Input uses emulated slots, so the internal
44
+ * behavior will not exactly match Select's slots.
45
+ * For example, Input does not render an actual `<slot>` element
46
+ * internally, so we do not check for that here. Instead,
47
+ * we check to see which label text is being used.
48
+ * If Input is updated to use Shadow DOM (and therefore native slots),
49
+ * then we can update these tests to more closely match the Select tests.
50
+ **/
51
+ describe('input: label rendering', () => {
52
+ it('should render label prop if only prop provided', async () => {
53
+ const page = await newSpecPage({
54
+ components: [Input],
55
+ html: `
56
+ <ion-input label="Label Prop Text"></ion-input>
57
+ `,
58
+ });
59
+ const input = page.body.querySelector('ion-input');
60
+ const labelText = input.querySelector('.label-text-wrapper');
61
+ expect(labelText.textContent).toBe('Label Prop Text');
62
+ });
63
+ it('should render label slot if only slot provided', async () => {
64
+ const page = await newSpecPage({
65
+ components: [Input],
66
+ html: `
67
+ <ion-input><div slot="label">Label Slot Text</div></ion-input>
68
+ `,
69
+ });
70
+ const input = page.body.querySelector('ion-input');
71
+ const labelText = input.querySelector('.label-text-wrapper');
72
+ expect(labelText.textContent).toBe('Label Slot Text');
73
+ });
74
+ it('should render label prop if both prop and slot provided', async () => {
75
+ const page = await newSpecPage({
76
+ components: [Input],
77
+ html: `
78
+ <ion-input label="Label Prop Text"><div slot="label">Label Slot Text</div></ion-input>
79
+ `,
80
+ });
81
+ const input = page.body.querySelector('ion-input');
82
+ const labelText = input.querySelector('.label-text-wrapper');
83
+ expect(labelText.textContent).toBe('Label Prop Text');
84
+ });
85
+ });
@@ -0,0 +1,24 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { newSpecPage } from "@stencil/core/testing";
5
+ import { Item } from "../../../item/item";
6
+ import { Input } from "../../input";
7
+ it('should render as modern when label is set asynchronously', async () => {
8
+ const page = await newSpecPage({
9
+ components: [Item, Input],
10
+ html: `
11
+ <ion-item>
12
+ <ion-input></ion-input>
13
+ </ion-item>
14
+ `,
15
+ });
16
+ const input = page.body.querySelector('ion-input');
17
+ // Template should be modern
18
+ expect(input.classList.contains('legacy-input')).toBe(false);
19
+ // Update the input label
20
+ input.label = 'New label';
21
+ await page.waitForChanges();
22
+ // Template should still be modern
23
+ expect(input.classList.contains('legacy-input')).toBe(false);
24
+ });
@@ -0,0 +1,48 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { newSpecPage } from "@stencil/core/testing";
5
+ import { List } from "../../../list/list";
6
+ import { RadioGroup } from "../../../radio-group/radio-group";
7
+ import { Radio } from "../../../radio/radio";
8
+ import { Item } from "../../item";
9
+ describe('ion-item', () => {
10
+ it('should not have a role when used without list', async () => {
11
+ const page = await newSpecPage({
12
+ components: [Item],
13
+ html: `<ion-item>Hello World</ion-item>`,
14
+ });
15
+ const item = page.body.querySelector('ion-item');
16
+ expect(item.getAttribute('role')).toBe(null);
17
+ });
18
+ it('should have a listitem role when used inside list', async () => {
19
+ const page = await newSpecPage({
20
+ components: [Item, List],
21
+ html: `
22
+ <ion-list>
23
+ <ion-item>
24
+ Hello World
25
+ </ion-item>
26
+ </ion-list>
27
+ `,
28
+ });
29
+ const item = page.body.querySelector('ion-item');
30
+ expect(item.getAttribute('role')).toBe('listitem');
31
+ });
32
+ it('should not have a role when used inside radio group and list', async () => {
33
+ const page = await newSpecPage({
34
+ components: [Radio, RadioGroup, Item, List],
35
+ html: `
36
+ <ion-list>
37
+ <ion-radio-group value="a">
38
+ <ion-item>
39
+ <ion-radio value="other-value" aria-label="my radio"></ion-radio>
40
+ </ion-item>
41
+ </ion-radio-group>
42
+ </ion-list>
43
+ `,
44
+ });
45
+ const item = page.body.querySelector('ion-item');
46
+ expect(item.getAttribute('role')).toBe(null);
47
+ });
48
+ });
@@ -0,0 +1,16 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { h } from "@stencil/core";
5
+ import { newSpecPage } from "@stencil/core/testing";
6
+ import { Loading } from "../../loading";
7
+ describe('loading: htmlAttributes inheritance', () => {
8
+ it('should correctly inherit attributes on host', async () => {
9
+ const page = await newSpecPage({
10
+ components: [Loading],
11
+ template: () => h("ion-loading", { overlayIndex: 1, htmlAttributes: { 'data-testid': 'basic-loading' } }),
12
+ });
13
+ const loading = page.body.querySelector('ion-loading');
14
+ await expect(loading.getAttribute('data-testid')).toBe('basic-loading');
15
+ });
16
+ });
@@ -0,0 +1,32 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { newSpecPage } from "@stencil/core/testing";
5
+ import { Loading } from "../loading";
6
+ it('loading should be assigned an incrementing id', async () => {
7
+ const page = await newSpecPage({
8
+ components: [Loading],
9
+ html: `<ion-loading is-open="true"></ion-loading>`,
10
+ });
11
+ let loading;
12
+ loading = page.body.querySelector('ion-loading');
13
+ expect(loading).not.toBe(null);
14
+ expect(loading.getAttribute('id')).toBe('ion-overlay-1');
15
+ // Remove the loading from the DOM
16
+ loading.remove();
17
+ await page.waitForChanges();
18
+ // Create a new loading to verify the id is incremented
19
+ loading = document.createElement('ion-loading');
20
+ loading.isOpen = true;
21
+ page.body.appendChild(loading);
22
+ await page.waitForChanges();
23
+ loading = page.body.querySelector('ion-loading');
24
+ expect(loading.getAttribute('id')).toBe('ion-overlay-2');
25
+ // Presenting the same loading again should reuse the existing id
26
+ loading.isOpen = false;
27
+ await page.waitForChanges();
28
+ loading.isOpen = true;
29
+ await page.waitForChanges();
30
+ loading = page.body.querySelector('ion-loading');
31
+ expect(loading.getAttribute('id')).toBe('ion-overlay-2');
32
+ });
@@ -0,0 +1,37 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { newSpecPage } from "@stencil/core/testing";
5
+ import { config } from "../../../global/config";
6
+ import { Loading } from "../loading";
7
+ describe('loading: custom html', () => {
8
+ it('should not allow for custom html by default', async () => {
9
+ const page = await newSpecPage({
10
+ components: [Loading],
11
+ html: `<ion-loading message="<button class='custom-html'>Custom Text</button>"></ion-loading>`,
12
+ });
13
+ const content = page.body.querySelector('.loading-content');
14
+ expect(content.textContent).toContain('Custom Text');
15
+ expect(content.querySelector('button.custom-html')).toBe(null);
16
+ });
17
+ it('should allow for custom html', async () => {
18
+ config.reset({ innerHTMLTemplatesEnabled: true });
19
+ const page = await newSpecPage({
20
+ components: [Loading],
21
+ html: `<ion-loading message="<button class='custom-html'>Custom Text</button>"></ion-loading>`,
22
+ });
23
+ const content = page.body.querySelector('.loading-content');
24
+ expect(content.textContent).toContain('Custom Text');
25
+ expect(content.querySelector('button.custom-html')).not.toBe(null);
26
+ });
27
+ it('should not allow for custom html', async () => {
28
+ config.reset({ innerHTMLTemplatesEnabled: false });
29
+ const page = await newSpecPage({
30
+ components: [Loading],
31
+ html: `<ion-loading message="<button class='custom-html'>Custom Text</button>"></ion-loading>`,
32
+ });
33
+ const content = page.body.querySelector('.loading-content');
34
+ expect(content.textContent).toContain('Custom Text');
35
+ expect(content.querySelector('button.custom-html')).toBe(null);
36
+ });
37
+ });
@@ -0,0 +1,22 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { newSpecPage } from "@stencil/core/testing";
5
+ import { Modal } from "../../modal";
6
+ describe('modal: a11y', () => {
7
+ it('should allow for custom role', async () => {
8
+ /**
9
+ * Note: This example should not be used in production.
10
+ * This only serves to check that `role` can be customized.
11
+ */
12
+ const page = await newSpecPage({
13
+ components: [Modal],
14
+ html: `
15
+ <ion-modal role="alertdialog"></ion-modal>
16
+ `,
17
+ });
18
+ const modal = page.body.querySelector('ion-modal');
19
+ const modalWrapper = modal.shadowRoot.querySelector('.modal-wrapper');
20
+ await expect(modalWrapper.getAttribute('role')).toBe('alertdialog');
21
+ });
22
+ });
@@ -0,0 +1,16 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { h } from "@stencil/core";
5
+ import { newSpecPage } from "@stencil/core/testing";
6
+ import { Modal } from "../../modal";
7
+ describe('modal: htmlAttributes inheritance', () => {
8
+ it('should correctly inherit attributes on host', async () => {
9
+ const page = await newSpecPage({
10
+ components: [Modal],
11
+ template: () => h("ion-modal", { htmlAttributes: { 'data-testid': 'basic-modal' }, overlayIndex: 1 }),
12
+ });
13
+ const modal = page.body.querySelector('ion-modal');
14
+ await expect(modal.getAttribute('data-testid')).toBe('basic-modal');
15
+ });
16
+ });
@@ -0,0 +1,191 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { h, setMode } from "@stencil/core";
5
+ import { newSpecPage } from "@stencil/core/testing";
6
+ import { Content } from "../../../content/content";
7
+ import { Modal } from "../../modal";
8
+ describe('modal: canDismiss', () => {
9
+ describe('modal: regular modal', () => {
10
+ it('should dismiss when canDismiss is true', async () => {
11
+ const page = await newSpecPage({
12
+ components: [Modal],
13
+ template: () => h("ion-modal", { overlayIndex: 1, animated: false, canDismiss: true }),
14
+ });
15
+ const modal = page.body.querySelector('ion-modal');
16
+ await modal.present();
17
+ await page.waitForChanges();
18
+ const returnValue = await modal.dismiss();
19
+ await expect(returnValue).toBe(true);
20
+ });
21
+ it('should not dismiss when canDismiss is false', async () => {
22
+ const page = await newSpecPage({
23
+ components: [Modal],
24
+ template: () => h("ion-modal", { overlayIndex: 1, animated: false, canDismiss: false }),
25
+ });
26
+ const modal = page.body.querySelector('ion-modal');
27
+ await modal.present();
28
+ await page.waitForChanges();
29
+ const returnValue = await modal.dismiss();
30
+ await expect(returnValue).toBe(false);
31
+ });
32
+ it('should dismiss when canDismiss is Promise<true>', async () => {
33
+ const page = await newSpecPage({
34
+ components: [Modal],
35
+ template: () => (h("ion-modal", { overlayIndex: 1, animated: false, canDismiss: () => {
36
+ return new Promise((resolve) => {
37
+ setTimeout(() => resolve(true), 50);
38
+ });
39
+ } })),
40
+ });
41
+ const modal = page.body.querySelector('ion-modal');
42
+ await modal.present();
43
+ await page.waitForChanges();
44
+ const returnValue = await modal.dismiss();
45
+ await expect(returnValue).toBe(true);
46
+ });
47
+ it('should not dismiss when canDismiss is Promise<false>', async () => {
48
+ const page = await newSpecPage({
49
+ components: [Modal],
50
+ template: () => (h("ion-modal", { overlayIndex: 1, animated: false, canDismiss: () => {
51
+ return new Promise((resolve) => {
52
+ setTimeout(() => resolve(false), 50);
53
+ });
54
+ } })),
55
+ });
56
+ const modal = page.body.querySelector('ion-modal');
57
+ await modal.present();
58
+ await page.waitForChanges();
59
+ const returnValue = await modal.dismiss();
60
+ await expect(returnValue).toBe(false);
61
+ });
62
+ });
63
+ describe('modal: card modal', () => {
64
+ beforeEach(() => {
65
+ /**
66
+ * Card modal is only available on iOS
67
+ */
68
+ setMode(() => 'ios');
69
+ });
70
+ it('should dismiss when canDismiss is true', async () => {
71
+ const page = await newSpecPage({
72
+ components: [Content, Modal],
73
+ template: () => (h("ion-modal", { overlayIndex: 1, presentingElement: document.createElement('div'), animated: false, canDismiss: true }, h("ion-content", null, "Test Content"))),
74
+ });
75
+ const modal = page.body.querySelector('ion-modal');
76
+ await modal.present();
77
+ await page.waitForChanges();
78
+ const returnValue = await modal.dismiss();
79
+ await expect(returnValue).toBe(true);
80
+ });
81
+ it('should not dismiss when canDismiss is false', async () => {
82
+ const page = await newSpecPage({
83
+ components: [Content, Modal],
84
+ template: () => (h("ion-modal", { overlayIndex: 1, presentingElement: document.createElement('div'), animated: false, canDismiss: false }, h("ion-content", null, "Test Content"))),
85
+ });
86
+ const modal = page.body.querySelector('ion-modal');
87
+ await modal.present();
88
+ await page.waitForChanges();
89
+ const returnValue = await modal.dismiss();
90
+ await expect(returnValue).toBe(false);
91
+ });
92
+ it('should dismiss when canDismiss is Promise<true>', async () => {
93
+ const page = await newSpecPage({
94
+ components: [Content, Modal],
95
+ template: () => (h("ion-modal", { overlayIndex: 1, presentingElement: document.createElement('div'), animated: false, canDismiss: () => {
96
+ return new Promise((resolve) => {
97
+ setTimeout(() => resolve(true), 50);
98
+ });
99
+ } }, h("ion-content", null, "Test Content"))),
100
+ });
101
+ const modal = page.body.querySelector('ion-modal');
102
+ await modal.present();
103
+ await page.waitForChanges();
104
+ const returnValue = await modal.dismiss();
105
+ await expect(returnValue).toBe(true);
106
+ });
107
+ it('should not dismiss when canDismiss is Promise<false>', async () => {
108
+ const page = await newSpecPage({
109
+ components: [Content, Modal],
110
+ template: () => (h("ion-modal", { overlayIndex: 1, presentingElement: document.createElement('div'), animated: false, canDismiss: () => {
111
+ return new Promise((resolve) => {
112
+ setTimeout(() => resolve(false), 50);
113
+ });
114
+ } }, h("ion-content", null, "Test Content"))),
115
+ });
116
+ const modal = page.body.querySelector('ion-modal');
117
+ await modal.present();
118
+ await page.waitForChanges();
119
+ const returnValue = await modal.dismiss();
120
+ await expect(returnValue).toBe(false);
121
+ });
122
+ });
123
+ describe('modal: sheet modal', () => {
124
+ it('should dismiss when canDismiss is true', async () => {
125
+ const page = await newSpecPage({
126
+ components: [Modal],
127
+ template: () => (h("ion-modal", { overlayIndex: 1, breakpoints: [0, 1], initialBreakpoint: 1, animated: false, canDismiss: true })),
128
+ });
129
+ const modal = page.body.querySelector('ion-modal');
130
+ await modal.present();
131
+ await page.waitForChanges();
132
+ const returnValue = await modal.dismiss();
133
+ await expect(returnValue).toBe(true);
134
+ });
135
+ it('should not dismiss when canDismiss is false', async () => {
136
+ const page = await newSpecPage({
137
+ components: [Modal],
138
+ template: () => (h("ion-modal", { overlayIndex: 1, breakpoints: [0, 1], initialBreakpoint: 1, animated: false, canDismiss: false })),
139
+ });
140
+ const modal = page.body.querySelector('ion-modal');
141
+ await modal.present();
142
+ await page.waitForChanges();
143
+ const returnValue = await modal.dismiss();
144
+ await expect(returnValue).toBe(false);
145
+ });
146
+ it('should dismiss when canDismiss is Promise<true>', async () => {
147
+ const page = await newSpecPage({
148
+ components: [Modal],
149
+ template: () => (h("ion-modal", { overlayIndex: 1, breakpoints: [0, 1], initialBreakpoint: 1, animated: false, canDismiss: () => {
150
+ return new Promise((resolve) => {
151
+ setTimeout(() => resolve(true), 50);
152
+ });
153
+ } })),
154
+ });
155
+ const modal = page.body.querySelector('ion-modal');
156
+ await modal.present();
157
+ await page.waitForChanges();
158
+ const returnValue = await modal.dismiss();
159
+ await expect(returnValue).toBe(true);
160
+ });
161
+ it('should not dismiss when canDismiss is Promise<false>', async () => {
162
+ const page = await newSpecPage({
163
+ components: [Modal],
164
+ template: () => (h("ion-modal", { overlayIndex: 1, breakpoints: [0, 1], initialBreakpoint: 1, animated: false, canDismiss: () => {
165
+ return new Promise((resolve) => {
166
+ setTimeout(() => resolve(false), 50);
167
+ });
168
+ } })),
169
+ });
170
+ const modal = page.body.querySelector('ion-modal');
171
+ await modal.present();
172
+ await page.waitForChanges();
173
+ const returnValue = await modal.dismiss();
174
+ await expect(returnValue).toBe(false);
175
+ });
176
+ });
177
+ describe('modal: data and role', () => {
178
+ test('should pass data and role when calling dismiss', async () => {
179
+ const canDismiss = jest.fn();
180
+ const page = await newSpecPage({
181
+ components: [Modal],
182
+ template: () => h("ion-modal", { overlayIndex: 1, animated: false, canDismiss: canDismiss }),
183
+ });
184
+ const modal = page.body.querySelector('ion-modal');
185
+ await modal.present();
186
+ await page.waitForChanges();
187
+ await modal.dismiss('my data', 'my role');
188
+ expect(canDismiss).toHaveBeenCalledWith('my data', 'my role');
189
+ });
190
+ });
191
+ });
@@ -0,0 +1,32 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { newSpecPage } from "@stencil/core/testing";
5
+ import { Modal } from "../modal";
6
+ it('modal should be assigned an incrementing id', async () => {
7
+ const page = await newSpecPage({
8
+ components: [Modal],
9
+ html: `<ion-modal is-open="true"></ion-modal>`,
10
+ });
11
+ let modal;
12
+ modal = page.body.querySelector('ion-modal');
13
+ expect(modal).not.toBe(null);
14
+ expect(modal.getAttribute('id')).toBe('ion-overlay-1');
15
+ // Remove the modal from the DOM
16
+ modal.remove();
17
+ await page.waitForChanges();
18
+ // Create a new modal to verify the id is incremented
19
+ modal = document.createElement('ion-modal');
20
+ modal.isOpen = true;
21
+ page.body.appendChild(modal);
22
+ await page.waitForChanges();
23
+ modal = page.body.querySelector('ion-modal');
24
+ expect(modal.getAttribute('id')).toBe('ion-overlay-2');
25
+ // Presenting the same modal again should reuse the existing id
26
+ modal.isOpen = false;
27
+ await page.waitForChanges();
28
+ modal.isOpen = true;
29
+ await page.waitForChanges();
30
+ modal = page.body.querySelector('ion-modal');
31
+ expect(modal.getAttribute('id')).toBe('ion-overlay-2');
32
+ });