Skip to content

Commit 93ebc6e

Browse files
committed
test(scripts): replace mode with theme
1 parent 4a568a6 commit 93ebc6e

File tree

2 files changed

+69
-46
lines changed

2 files changed

+69
-46
lines changed

core/scripts/testing/scripts.js

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@
1414
* The following URL parameters are supported:
1515
* - `rtl`: Set to `true` to enable right-to-left directionality.
1616
* - `ionic:_testing`: Set to `true` to identify testing environments.
17-
* - `ionic:mode`: Set to `ios` or `md` to load a specific mode.
18-
* Defaults to `md`.
17+
* - `ionic:theme`: Set to `ionic`, `ios`, or `md` to load a specific
18+
* theme. Defaults to `md`.
1919
* - `palette`: Set to `light`, `dark`, `high-contrast`, or
2020
* `high-contrast-dark` to load a specific palette. Defaults to `light`.
2121
*/
2222

23-
(function() {
23+
const DEFAULT_THEME = 'md';
2424

25+
(function() {
26+
2527
/**
2628
* The `rtl` param is used to set the directionality of the
2729
* document. This can be `true` or `false`.
@@ -48,6 +50,34 @@
4850
document.head.appendChild(style);
4951
}
5052

53+
/**
54+
* The `theme` param is used to load a specific theme.
55+
* This can be `ionic`, `ios`, or `md`. Default to `md` for tests.
56+
*/
57+
const themeQuery = window.location.search.match(/ionic:theme=([a-z0-9]+)/i);
58+
const themeHash = window.location.hash.match(/ionic:theme=([a-z0-9]+)/i);
59+
const themeAttr = document.documentElement.getAttribute('theme');
60+
const themeName = themeQuery?.[1] || themeHash?.[1] || themeAttr || DEFAULT_THEME;
61+
62+
// TODO(): Remove this when the tokens are working for all components
63+
// and the themes all use the same bundle
64+
if ((themeQuery && themeQuery[1] === 'ionic') || themeAttr === 'ionic') {
65+
const ionicThemeLinkTag = document.querySelector('link[href*="css/ionic/bundle.ionic.css"]');
66+
67+
if (!ionicThemeLinkTag) {
68+
const linkTag = document.createElement('link');
69+
linkTag.setAttribute('rel', 'stylesheet');
70+
linkTag.setAttribute('type', 'text/css');
71+
linkTag.setAttribute('href', '/css/ionic/bundle.ionic.css');
72+
document.head.appendChild(linkTag);
73+
}
74+
75+
const defaultThemeLinkTag = document.querySelector('link[href*="css/ionic.bundle.css"]');
76+
if (defaultThemeLinkTag) {
77+
defaultThemeLinkTag.remove();
78+
}
79+
}
80+
5181
/**
5282
* The `palette` param is used to load a specific palette
5383
* for the theme.
@@ -63,46 +93,40 @@
6393

6494
const paletteName = paletteQuery?.[1] || paletteHash?.[1] || darkClass || 'light';
6595

66-
if (paletteName !== 'light') {
67-
const linkTag = document.createElement('link');
68-
linkTag.setAttribute('rel', 'stylesheet');
69-
linkTag.setAttribute('type', 'text/css');
70-
linkTag.setAttribute('href', `/css/palettes/${paletteName}.always.css`);
71-
document.head.appendChild(linkTag);
96+
// Load theme tokens if the theme is valid
97+
const validThemes = ['ionic', 'ios', 'md'];
98+
if (themeName && validThemes.includes(themeName)) {
99+
loadThemeTokens(themeName, paletteName);
100+
} else if(themeName) {
101+
console.warn(
102+
`Unsupported theme "${themeName}". Supported themes are: ${validThemes.join(', ')}. Defaulting to ${DEFAULT_THEME}.`
103+
);
72104
}
73105

74-
/**
75-
* The `ionic` theme uses a different stylesheet than the `iOS` and `md` themes.
76-
* This is to ensure that the `ionic` theme is loaded when the `ionic:theme=ionic`
77-
* or when the HTML tag has the `theme="ionic"` attribute. This is useful for
78-
* the snapshot tests, where the `ionic` theme is not loaded by default.
79-
*/
80-
const themeQuery = window.location.search.match(/ionic:theme=([a-z]+)/);
81-
const themeAttr = document.documentElement.getAttribute('theme');
82-
83-
if ((themeQuery && themeQuery[1] === 'ionic') || themeAttr === 'ionic') {
84-
const ionicThemeLinkTag = document.querySelector('link[href*="css/ionic/bundle.ionic.css"]');
106+
async function loadThemeTokens(themeName, paletteName) {
107+
try {
108+
// Load the default tokens for the theme
109+
const defaultTokens = await import(`/themes/${themeName}/default.tokens.js`);
110+
const theme = defaultTokens.defaultTheme;
85111

86-
if (!ionicThemeLinkTag) {
87-
const linkTag = document.createElement('link');
88-
linkTag.setAttribute('rel', 'stylesheet');
89-
linkTag.setAttribute('type', 'text/css');
90-
linkTag.setAttribute('href', '/css/ionic/bundle.ionic.css');
91-
document.head.appendChild(linkTag);
92-
}
112+
// If a specific palette is requested, modify the palette structure
113+
// to set the enabled property to 'always'
114+
if (paletteName === 'dark' && theme.palette?.dark) {
115+
theme.palette.dark.enabled = 'always';
116+
}
93117

94-
const utilsBundleLinkTag = document.querySelector('link[href*="css/utils.bundle.css"]');
95-
if (!utilsBundleLinkTag) {
96-
const linkTag = document.createElement('link');
97-
linkTag.setAttribute('rel', 'stylesheet');
98-
linkTag.setAttribute('type', 'text/css');
99-
linkTag.setAttribute('href', '/css/utils.bundle.css');
100-
document.head.appendChild(linkTag);
101-
}
118+
// Apply the theme tokens to Ionic config
119+
window.Ionic = window.Ionic || {};
120+
window.Ionic.config = window.Ionic.config || {};
121+
window.Ionic.config.customTheme = theme;
102122

103-
const defaultThemeLinkTag = document.querySelector('link[href*="css/ionic.bundle.css"]');
104-
if (defaultThemeLinkTag) {
105-
defaultThemeLinkTag.remove();
123+
// Re-apply the global theme
124+
if (window.Ionic.config.get && window.Ionic.config.set) {
125+
const themeModule = await import('/themes/utils/theme.js');
126+
themeModule.applyGlobalTheme(theme);
127+
}
128+
} catch (error) {
129+
console.error(`Failed to load theme tokens for ${themeName}:`, error);
106130
}
107131
}
108132

core/src/utils/test/playwright/page/utils/set-content.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,18 @@ export const setContent = async (page: Page, html: string, testInfo: TestInfo, o
1919

2020
let mode: Mode;
2121
let direction: Direction;
22-
let theme: Theme;
22+
let themeName: Theme;
2323
let palette: Palette;
2424

2525
if (options == undefined) {
2626
mode = testInfo.project.metadata.mode;
2727
direction = testInfo.project.metadata.rtl ? 'rtl' : 'ltr';
28-
theme = testInfo.project.metadata.theme;
28+
themeName = testInfo.project.metadata.theme;
2929
palette = testInfo.project.metadata.palette;
3030
} else {
3131
mode = options.mode;
3232
direction = options.direction;
33-
theme = options.theme;
33+
themeName = options.theme;
3434
palette = options.palette;
3535
}
3636

@@ -40,7 +40,7 @@ export const setContent = async (page: Page, html: string, testInfo: TestInfo, o
4040
// config passes in the importIonicFromCDN option. This is useful
4141
// when testing with the CDN version of Ionic.
4242
let ionicCSSImports =
43-
theme === 'ionic'
43+
themeName === 'ionic'
4444
? `
4545
<link href="${baseUrl}/css/ionic/bundle.ionic.css" rel="stylesheet" />
4646
<link href="${baseUrl}/css/utils.bundle.css" rel="stylesheet" />
@@ -54,7 +54,7 @@ export const setContent = async (page: Page, html: string, testInfo: TestInfo, o
5454

5555
if (options?.importIonicFromCDN) {
5656
ionicCSSImports =
57-
theme === 'ionic'
57+
themeName === 'ionic'
5858
? `
5959
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core/css/ionic/bundle.ionic.css" />
6060
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core/css/utils.bundle.css" />
@@ -77,14 +77,13 @@ export const setContent = async (page: Page, html: string, testInfo: TestInfo, o
7777
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
7878
${ionicCSSImports}
7979
<link href="${baseUrl}/scripts/testing/styles.css" rel="stylesheet" />
80-
${palette !== 'light' ? `<link href="${baseUrl}/css/palettes/${palette}.always.css" rel="stylesheet" />` : ''}
8180
<script src="${baseUrl}/scripts/testing/scripts.js"></script>
8281
${ionicJSImports}
8382
<script>
8483
window.Ionic = {
8584
config: {
8685
mode: '${mode}',
87-
theme: '${theme}'
86+
theme: '${themeName}',
8887
}
8988
}
9089
</script>
@@ -107,7 +106,7 @@ export const setContent = async (page: Page, html: string, testInfo: TestInfo, o
107106

108107
testInfo.annotations.push({
109108
type: 'theme',
110-
description: theme,
109+
description: themeName,
111110
});
112111

113112
if (baseUrl) {

0 commit comments

Comments
 (0)