diff --git a/core/src/components/button/test/clear/button.e2e.ts b/core/src/components/button/test/clear/button.e2e.ts index 6777705ffd5..a08d95ddc27 100644 --- a/core/src/components/button/test/clear/button.e2e.ts +++ b/core/src/components/button/test/clear/button.e2e.ts @@ -4,7 +4,7 @@ import { configs, test } from '@utils/test/playwright'; /** * Fill="clear" does not render differently based on the direction. */ -configs({ directions: ['ltr'], themes: ['ios', 'md', 'ionic'] }).forEach(({ title, config, screenshot }) => { +configs({ directions: ['ltr'], modes: ['ios', 'md', 'ionic-md'] }).forEach(({ title, config, screenshot }) => { test.describe(title('button: fill: clear'), () => { test('should not have visual regressions', async ({ page }) => { await page.goto(`/src/components/button/test/clear`, config); diff --git a/core/src/components/button/test/shape/button.e2e.ts b/core/src/components/button/test/shape/button.e2e.ts index 40af4fa1960..0682c07dc4c 100644 --- a/core/src/components/button/test/shape/button.e2e.ts +++ b/core/src/components/button/test/shape/button.e2e.ts @@ -74,7 +74,7 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => { /** * Shape="rectangular" is only available in the Ionic theme. */ -configs({ directions: ['ltr'], themes: ['ionic'] }).forEach(({ title, screenshot, config }) => { +configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ title, screenshot, config }) => { test.describe(title('button: shape'), () => { test.describe('rectangular', () => { test('should not have visual regressions', async ({ page }) => { diff --git a/core/src/components/button/test/size/button.e2e.ts b/core/src/components/button/test/size/button.e2e.ts index 94b941326ed..c833c77a891 100644 --- a/core/src/components/button/test/size/button.e2e.ts +++ b/core/src/components/button/test/size/button.e2e.ts @@ -1,8 +1,7 @@ import { expect } from '@playwright/test'; import { configs, test } from '@utils/test/playwright'; -// TODO: FW-6077 - Limit this test to just the Ionic theme on MD mode. -configs({ directions: ['ltr'], themes: ['ionic', 'md', 'ios'] }).forEach(({ title, screenshot, config }) => { +configs({ directions: ['ltr'], modes: ['ionic-md', 'md', 'ios'] }).forEach(({ title, screenshot, config }) => { test.describe(title('button: size'), () => { test('should render small buttons', async ({ page }) => { await page.setContent( @@ -65,7 +64,7 @@ configs({ directions: ['ltr'], themes: ['ionic', 'md', 'ios'] }).forEach(({ titl /** * The following tests are specific to the Ionic theme and do not depend on the text direction. */ -configs({ directions: ['ltr'], themes: ['ionic'] }).forEach(({ title, screenshot, config }) => { +configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ title, screenshot, config }) => { test.describe(title('button: size'), () => { test('should render xsmall buttons', async ({ page }) => { await page.setContent(`X-Small Button`, config); diff --git a/core/src/utils/test/playwright/generator.ts b/core/src/utils/test/playwright/generator.ts index 0c54407890d..3100b5c0d8f 100644 --- a/core/src/utils/test/playwright/generator.ts +++ b/core/src/utils/test/playwright/generator.ts @@ -1,6 +1,4 @@ -import { isModeValidForTheme } from '../../../global/ionic-global'; - -export type Mode = 'ios' | 'md'; +export type Mode = 'ios' | 'md' | 'ionic-ios' | 'ionic-md'; export type Direction = 'ltr' | 'rtl'; export type Theme = 'ios' | 'md' | 'ionic'; @@ -19,9 +17,9 @@ export type ScreenshotFn = (fileName: string) => string; export interface TestConfig { direction: Direction; - theme: Theme; palette: Palette; mode: Mode; + theme: Theme; } interface TestUtilities { @@ -31,14 +29,36 @@ interface TestUtilities { } interface TestConfigOption { + /** + * The available options to test against. + * - "ios": Test against iOS theme on iOS mode. + * - "md": Test against Material Design theme on Material Design mode. + * - "ionic-ios": Test against Ionic theme on iOS mode. + * - "ionic-md": Test against Ionic theme on Material Design mode. + * + * If unspecified, tests will run against "ios" and "md". + */ modes?: Mode[]; + /** + * The text direction to test against. + * + * - "ltr": Test against left-to-right direction. + * - "rtl": Test against right-to-left direction. + * + * If unspecified, tests will run against both directions. + */ directions?: Direction[]; - palettes?: Palette[]; /** - * The individual themes (iOS, Material Design and Ionic) to test - * against. If unspecified, defaults iOS and Material Design + * The color palette to test against. + * + * - "light": Test against light palette. + * - "dark": Test against dark palette. + * - "high-contrast": Test against high contrast light palette. + * - "high-contrast-dark": Test against high contrast dark palette. + * + * If unspecified, tests will run against light theme. */ - themes?: Theme[]; + palettes?: Palette[]; } /** @@ -48,14 +68,17 @@ interface TestConfigOption { * each test title is unique. */ const generateTitle = (title: string, config: TestConfig): string => { - const { direction, palette, theme, mode } = config; - - if (theme === mode) { - /** - * Fallback to the old test title naming convention - * when the theme and mode are the same. - */ + const { direction, palette, mode, theme } = config; + /** + * The iOS theme can only be used with the iOS mode, + * and the MD theme can only be used with the MD mode. + * + * This logic enables the fallback behavior for existing tests, + * where we only tested against a mode, which accounted for both + * the theme and mode. + */ + if (theme === 'ios' || theme === 'md') { if (palette === 'light') { /** * Ionic has many existing tests that existed prior to @@ -63,10 +86,9 @@ const generateTitle = (title: string, config: TestConfig): string => { * compatibility, we will not include the theme in the test * title if the theme is set to light. */ - return `${title} - ${theme}/${direction}`; + return `${title} - ${mode}/${direction}`; } - - return `${title} - ${theme}/${direction}/${palette}`; + return `${title} - ${mode}/${direction}/${palette}`; } return `${title} - ${theme}/${mode}/${direction}/${palette}`; @@ -77,13 +99,16 @@ const generateTitle = (title: string, config: TestConfig): string => { * and a test config. */ const generateScreenshotName = (fileName: string, config: TestConfig): string => { - const { theme, direction, palette, mode } = config; - - if (theme === mode) { - /** - * Fallback to the old screenshot naming convention - * when the theme and mode are the same. - */ + const { direction, palette, mode, theme } = config; + /** + * The iOS theme can only be used with the iOS mode, + * and the MD theme can only be used with the MD mode. + * + * This logic enables the fallback behavior for existing tests, + * where we only tested against a mode, which accounted for both + * the theme and mode. + */ + if (theme === 'ios' || theme === 'md') { if (palette === 'light') { /** * Ionic has many existing tests that existed prior to @@ -91,10 +116,9 @@ const generateScreenshotName = (fileName: string, config: TestConfig): string => * compatibility, we will not include the theme in the screenshot * name if the theme is set to light. */ - return `${fileName}-${theme}-${direction}.png`; + return `${fileName}-${mode}-${direction}.png`; } - - return `${fileName}-${theme}-${direction}-${palette}.png`; + return `${fileName}-${mode}-${direction}-${palette}.png`; } return `${fileName}-${theme}-${mode}-${direction}-${palette}.png`; @@ -104,7 +128,7 @@ const generateScreenshotName = (fileName: string, config: TestConfig): string => * Given a config generate an array of test variants. */ export const configs = (testConfig: TestConfigOption = DEFAULT_TEST_CONFIG_OPTION): TestUtilities[] => { - const { modes, themes, directions } = testConfig; + const { modes, directions } = testConfig; const configs: TestConfig[] = []; @@ -113,19 +137,17 @@ export const configs = (testConfig: TestConfigOption = DEFAULT_TEST_CONFIG_OPTIO * fall back to the defaults. */ const processedModes = modes ?? DEFAULT_MODES; - const processedTheme = themes ?? DEFAULT_THEMES; const processedDirection = directions ?? DEFAULT_DIRECTIONS; const processedPalette = testConfig.palettes ?? DEFAULT_PALETTES; processedModes.forEach((mode) => { - processedTheme.forEach((theme) => { - if (!isModeValidForTheme(mode, theme)) { - return; - } - processedDirection.forEach((direction) => { - processedPalette.forEach((palette) => { - configs.push({ theme, direction, palette, mode }); - }); + const [themeOrCombinedMode, modeName] = mode.split('-') as [Theme, Mode]; + const parsedTheme = themeOrCombinedMode; + const parsedMode = modeName ?? themeOrCombinedMode; + + processedDirection.forEach((direction) => { + processedPalette.forEach((palette) => { + configs.push({ direction, palette, mode: parsedMode, theme: parsedTheme }); }); }); }); @@ -140,13 +162,11 @@ export const configs = (testConfig: TestConfigOption = DEFAULT_TEST_CONFIG_OPTIO }; const DEFAULT_MODES: Mode[] = ['ios', 'md']; -const DEFAULT_THEMES: Theme[] = ['ios', 'md']; const DEFAULT_DIRECTIONS: Direction[] = ['ltr', 'rtl']; const DEFAULT_PALETTES: Palette[] = ['light']; const DEFAULT_TEST_CONFIG_OPTION = { modes: DEFAULT_MODES, - themes: DEFAULT_THEMES, directions: DEFAULT_DIRECTIONS, palettes: DEFAULT_PALETTES, };