diff --git a/core/src/components/app/test/safe-area/app.e2e.ts b/core/src/components/app/test/safe-area/app.e2e.ts index f2f5c8872e2..336cdffcc45 100644 --- a/core/src/components/app/test/safe-area/app.e2e.ts +++ b/core/src/components/app/test/safe-area/app.e2e.ts @@ -18,20 +18,66 @@ configs({ directions: ['ltr'] }).forEach(({ config, title, screenshot }) => { await expect(page).toHaveScreenshot(screenshot(`app-${screenshotModifier}-diff`)); }; + test.beforeEach(async ({ page }) => { await page.goto(`/src/components/app/test/safe-area`, config); }); - test('should not have visual regressions with action sheet', async ({ page }) => { - await testOverlay(page, '#show-action-sheet', 'ionActionSheetDidPresent', 'action-sheet'); - }); - test('should not have visual regressions with menu', async ({ page }) => { - await testOverlay(page, '#show-menu', 'ionDidOpen', 'menu'); - }); - test('should not have visual regressions with picker', async ({ page }) => { - await testOverlay(page, '#show-picker', 'ionPickerDidPresent', 'picker'); + + test.describe(title('Ionic safe area variables'), () => { + test.beforeEach(async ({ page }) => { + const htmlTag = page.locator('html'); + const hasSafeAreaClass = await htmlTag.evaluate((el) => el.classList.contains('safe-area')); + + expect(hasSafeAreaClass).toBe(true); + }); + + test('should not have visual regressions with action sheet', async ({ page }) => { + await testOverlay(page, '#show-action-sheet', 'ionActionSheetDidPresent', 'action-sheet'); + }); + test('should not have visual regressions with menu', async ({ page }) => { + await testOverlay(page, '#show-menu', 'ionDidOpen', 'menu'); + }); + test('should not have visual regressions with picker', async ({ page }) => { + await testOverlay(page, '#show-picker', 'ionPickerDidPresent', 'picker'); + }); + test('should not have visual regressions with toast', async ({ page }) => { + await testOverlay(page, '#show-toast', 'ionToastDidPresent', 'toast'); + }); }); - test('should not have visual regressions with toast', async ({ page }) => { - await testOverlay(page, '#show-toast', 'ionToastDidPresent', 'toast'); + + test.describe(title('Capacitor safe area variables'), () => { + test('should use safe-area-inset vars when safe-area class is not defined', async ({ page }) => { + await page.evaluate(() => { + const html = document.documentElement; + + // Remove the safe area class + html.classList.remove('safe-area'); + + // Set the safe area inset variables + html.style.setProperty('--safe-area-inset-top', '10px'); + html.style.setProperty('--safe-area-inset-bottom', '20px'); + html.style.setProperty('--safe-area-inset-left', '30px'); + html.style.setProperty('--safe-area-inset-right', '40px'); + }); + + const top = await page.evaluate(() => + getComputedStyle(document.documentElement).getPropertyValue('--ion-safe-area-top').trim() + ); + const bottom = await page.evaluate(() => + getComputedStyle(document.documentElement).getPropertyValue('--ion-safe-area-bottom').trim() + ); + const left = await page.evaluate(() => + getComputedStyle(document.documentElement).getPropertyValue('--ion-safe-area-left').trim() + ); + const right = await page.evaluate(() => + getComputedStyle(document.documentElement).getPropertyValue('--ion-safe-area-right').trim() + ); + + expect(top).toBe('10px'); + expect(bottom).toBe('20px'); + expect(left).toBe('30px'); + expect(right).toBe('40px'); + }); }); }); }); diff --git a/core/src/css/core.scss b/core/src/css/core.scss index db694fc6a07..c7f7357ab46 100644 --- a/core/src/css/core.scss +++ b/core/src/css/core.scss @@ -252,10 +252,12 @@ html.plt-ios.plt-hybrid, html.plt-ios.plt-pwa { @supports (padding-top: env(safe-area-inset-top)) { html { - --ion-safe-area-top: env(safe-area-inset-top); - --ion-safe-area-bottom: env(safe-area-inset-bottom); - --ion-safe-area-left: env(safe-area-inset-left); - --ion-safe-area-right: env(safe-area-inset-right); + // `--safe-area-inset-*` are set by Capacitor + // @see https://capacitorjs.com/docs/apis/system-bars#android-note + --ion-safe-area-top: var(--safe-area-inset-top, env(safe-area-inset-top)); + --ion-safe-area-bottom: var(--safe-area-inset-bottom, env(safe-area-inset-bottom)); + --ion-safe-area-left: var(--safe-area-inset-left, env(safe-area-inset-left)); + --ion-safe-area-right: var(--safe-area-inset-right, env(safe-area-inset-right)); } }