Skip to content

Commit eee9f14

Browse files
committed
test(toast): add e2e test for subtle and improve positioning using inline toasts
1 parent a786cc1 commit eee9f14

8 files changed

+122
-100
lines changed

core/src/components/toast/test/hue/index.html

Lines changed: 63 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@
1414
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
1515
</head>
1616

17-
<script type="module">
18-
import { toastController } from '../../../../dist/ionic/index.esm.js';
19-
window.toastController = toastController;
20-
</script>
21-
2217
<body>
2318
<ion-app>
2419
<ion-header>
@@ -33,120 +28,88 @@
3328
demo purposes only.
3429
</p>
3530

36-
<button class="expand" onclick="openAllToasts(false)">Show All Subtle Toasts</button>
37-
<button class="expand" onclick="openAllToasts(true)">Show All Bold Toasts</button>
31+
<button id="show-subtle-toasts" class="expand">Show All Subtle Toasts</button>
32+
<button id="show-bold-toasts" class="expand">Show All Bold Toasts</button>
3833
</ion-content>
3934

40-
<div id="toastBackdrop" class="backdrop"></div>
35+
<div id="backdrop" class="backdrop"></div>
36+
37+
<ion-toast position="top"></ion-toast>
38+
<ion-toast color="primary" position="top"></ion-toast>
39+
<ion-toast color="secondary" position="top"></ion-toast>
40+
<ion-toast color="tertiary" position="top"></ion-toast>
41+
<ion-toast color="success" position="top"></ion-toast>
42+
<ion-toast color="warning" position="top"></ion-toast>
43+
<ion-toast color="danger" position="top"></ion-toast>
44+
<ion-toast color="light" position="top"></ion-toast>
45+
<ion-toast color="medium" position="top"></ion-toast>
46+
<ion-toast color="dark" position="top"></ion-toast>
4147
</ion-app>
4248

43-
<script>
44-
const colorIconMap = {
45-
primary: { color: 'primary', icon: 'alert-circle' },
46-
secondary: { color: 'secondary', icon: 'information-circle' },
47-
tertiary: { color: 'tertiary', icon: 'alert-circle' },
48-
success: { color: 'success', icon: 'checkmark-circle' },
49-
warning: { color: 'warning', icon: 'warning' },
50-
danger: { color: 'danger', icon: 'alert-circle' },
51-
light: { color: 'light', icon: 'alert-circle' },
52-
medium: { color: 'medium', icon: 'alert-circle' },
53-
dark: { color: 'dark', icon: 'alert-circle' },
54-
};
55-
let toastCount = 0;
56-
let activeToasts = [];
57-
58-
// Show backdrop when toasts are presented
59-
function showBackdrop() {
60-
const backdrop = document.getElementById('toastBackdrop');
61-
backdrop.style.display = 'block';
62-
backdrop.addEventListener('click', closeAllToasts);
63-
}
49+
<script type="module">
50+
let lastToast = null;
51+
let toastOffset = 10;
6452

65-
// Hide backdrop when all toasts are dismissed
66-
function hideBackdrop() {
67-
const backdrop = document.getElementById('toastBackdrop');
68-
if (toastCount === 0) {
69-
backdrop.style.display = 'none';
70-
backdrop.removeEventListener('click', closeAllToasts);
71-
}
72-
}
53+
// Show all toasts when the button is clicked
54+
function openAllToasts(isBold) {
55+
toastOffset = 10;
56+
57+
const toasts = document.querySelectorAll('ion-toast');
58+
59+
toasts.forEach((toast, index) => {
60+
toast.removeAttribute('hue');
61+
toast.hue = isBold ? 'bold' : 'subtle';
62+
const hue = toast.hue;
63+
64+
const color = toast.color || 'default';
65+
toast.message = `This is a ${hue} ${color} toast.`;
66+
67+
toast.buttons = [{
68+
text: 'Action',
69+
role: 'cancel'
70+
}];
7371

74-
// Close all toasts when the backdrop is clicked
75-
function closeAllToasts() {
76-
activeToasts.forEach((toast) => {
77-
toast.dismiss();
72+
// Set dynamic position for each toast to ensure they don't overlap
73+
toast.style.position = 'absolute';
74+
toast.style.top = `${toastOffset}px`;
75+
toast.style.left = '50%';
76+
toast.style.transform = 'translateX(-50%)';
77+
78+
toast.present();
79+
80+
// Update the toastOffset for the next toast to ensure it's positioned below the previous one
81+
toastOffset += 60;
7882
});
79-
toastCount = 0;
80-
activeToasts = [];
81-
hideBackdrop();
82-
}
8383

84-
async function openToast(opts, delay = 0) {
85-
setTimeout(async () => {
86-
const yOffset = toastCount * 60;
87-
toastCount++;
88-
89-
const toast = await toastController.create({
90-
...opts,
91-
position: 'top',
92-
animated: false,
93-
});
94-
95-
await toast.present();
96-
activeToasts.push(toast);
97-
98-
showBackdrop();
99-
100-
requestAnimationFrame(() => {
101-
const toastEl = document.querySelector('ion-toast:last-of-type');
102-
if (toastEl) {
103-
toastEl.style.position = 'absolute';
104-
toastEl.style.left = '50%';
105-
toastEl.style.transform = 'translateX(-50%)';
106-
toastEl.style.top = `${10 + yOffset}px`;
107-
}
108-
});
109-
110-
toast.onDidDismiss().then(() => {
111-
toastCount--;
112-
activeToasts = activeToasts.filter((t) => t !== toast);
113-
hideBackdrop();
114-
});
115-
}, delay);
84+
document.getElementById("backdrop").style.display = "block";
11685
}
11786

118-
// Show all toasts sequentially with a slight delay between each
119-
function openAllToasts(isBold) {
120-
toastCount = 0;
121-
activeToasts = [];
122-
123-
Object.values(colorIconMap).forEach((item, index) => {
124-
openToast(
125-
{
126-
message: `This is a ${item.color} toast.`,
127-
buttons: [{ text: 'Action' }, { icon: 'close', role: 'cancel' }],
128-
color: item.color,
129-
icon: item.icon,
130-
...(isBold ? { hue: 'bold' } : {}),
131-
},
132-
index * 150
133-
);
134-
});
87+
// Dismiss all toasts when backdrop is clicked
88+
function dismissAllToasts() {
89+
const toasts = document.querySelectorAll('ion-toast');
90+
toasts.forEach(toast => toast.dismiss());
91+
92+
document.getElementById("backdrop").style.display = "none";
13593
}
94+
95+
document.addEventListener("DOMContentLoaded", function () {
96+
document.getElementById("show-subtle-toasts").addEventListener("click", () => openAllToasts(false));
97+
document.getElementById("show-bold-toasts").addEventListener("click", () => openAllToasts(true));
98+
99+
document.getElementById("backdrop").addEventListener("click", dismissAllToasts);
100+
});
136101
</script>
137102

138103
<style>
139104
.backdrop {
140105
position: fixed;
141106
top: 0;
142107
left: 0;
143-
width: 100%;
144-
height: 100%;
145-
background-color: rgba(0, 0, 0, 0.5);
108+
right: 0;
109+
bottom: 0;
110+
background: rgba(0, 0, 0, 0.5);
111+
z-index: 1000;
146112
display: none;
147-
z-index: 9998;
148-
pointer-events: all;
149-
backdrop-filter: blur(5px);
150113
}
151114
</style>
152115
</body>
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { expect } from '@playwright/test';
2+
import type { E2EPage, E2EPageOptions, ScreenshotFn, EventSpy } from '@utils/test/playwright';
3+
import { configs, test } from '@utils/test/playwright';
4+
5+
class ToastFixture {
6+
readonly page: E2EPage;
7+
8+
private ionToastDidPresent!: EventSpy;
9+
10+
constructor(page: E2EPage) {
11+
this.page = page;
12+
}
13+
14+
async goto(config: E2EPageOptions) {
15+
const { page } = this;
16+
await page.goto(`/src/components/toast/test/hue`, config);
17+
this.ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent');
18+
}
19+
20+
async openToast(selector: string) {
21+
const { page, ionToastDidPresent } = this;
22+
const button = page.locator(selector);
23+
await button.click();
24+
25+
await ionToastDidPresent.next();
26+
27+
return {
28+
toast: page.locator('ion-toast'),
29+
};
30+
}
31+
32+
async screenshot(screenshotModifier: string, screenshot: ScreenshotFn) {
33+
const { page } = this;
34+
35+
const screenshotString = screenshot(`toast-${screenshotModifier}`);
36+
37+
await expect(page).toHaveScreenshot(screenshotString);
38+
}
39+
}
40+
41+
configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ title, screenshot, config }) => {
42+
test.describe(title('toast: hue'), () => {
43+
let toastFixture: ToastFixture;
44+
test.beforeEach(async ({ page }) => {
45+
toastFixture = new ToastFixture(page);
46+
await toastFixture.goto(config);
47+
});
48+
49+
test('should show all subtle toasts', async () => {
50+
await toastFixture.openToast('#show-subtle-toasts');
51+
await toastFixture.screenshot('subtle', screenshot);
52+
});
53+
54+
test('should show all bold toasts', async () => {
55+
await toastFixture.openToast('#show-bold-toasts');
56+
await toastFixture.screenshot('bold', screenshot);
57+
});
58+
});
59+
});
54.2 KB
Loading
71.5 KB
Loading
66.7 KB
Loading
55.2 KB
Loading
74.3 KB
Loading
70.9 KB
Loading

0 commit comments

Comments
 (0)