mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-08 15:51:16 +08:00
fix(platform): account for larger tablets (#17630)
* fix(platform): account for larger tablets * lint files * add utils file, clean up tests, add more tests * update tests with extra desktop checks * change window to win
This commit is contained in:
@ -35,6 +35,10 @@ const isIOS = (win: Window) =>
|
||||
const isAndroid = (win: Window) =>
|
||||
testUserAgent(win, /android|sink/i);
|
||||
|
||||
const isAndroidTablet = (win: Window) => {
|
||||
return isAndroid(win) && !testUserAgent(win, /mobile/i);
|
||||
};
|
||||
|
||||
const isPhablet = (win: Window) => {
|
||||
const width = win.innerWidth;
|
||||
const height = win.innerHeight;
|
||||
@ -50,8 +54,15 @@ const isTablet = (win: Window) => {
|
||||
const height = win.innerHeight;
|
||||
const smallest = Math.min(width, height);
|
||||
const largest = Math.max(width, height);
|
||||
return (smallest > 460 && smallest < 820) &&
|
||||
(largest > 780 && largest < 1400);
|
||||
|
||||
return (
|
||||
isIpad(win) ||
|
||||
isAndroidTablet(win) ||
|
||||
(
|
||||
(smallest > 460 && smallest < 820) &&
|
||||
(largest > 780 && largest < 1400)
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
const isMobile = (win: Window) =>
|
||||
|
||||
@ -1,121 +1,118 @@
|
||||
import { testUserAgent, getPlatforms, isPlatform } from '../platform';
|
||||
import { PlatformConfiguration, configureBrowser } from './platform.utils';
|
||||
|
||||
enum PlatformConfiguration {
|
||||
AndroidTablet = {
|
||||
navigator: {
|
||||
userAgent: 'Mozilla/5.0 (Linux; Android 7.0; Pixel C Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/52.0.2743.98 Safari/537.36'
|
||||
},
|
||||
innerWidth: 800,
|
||||
innerHeight: 1200
|
||||
},
|
||||
Capacitor = {
|
||||
Capacitor: {
|
||||
isNative: true
|
||||
}
|
||||
},
|
||||
Cordova = {
|
||||
cordova: true
|
||||
},
|
||||
DesktopSafari = {
|
||||
navigator: {
|
||||
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9'
|
||||
},
|
||||
innerWidth: 1920,
|
||||
innerHeight: 1080
|
||||
},
|
||||
iPhone = {
|
||||
navigator: {
|
||||
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1'
|
||||
},
|
||||
innerWidth: 375,
|
||||
innerHeight: 812
|
||||
}
|
||||
}
|
||||
|
||||
describe('Platform Tests', () => {
|
||||
/**
|
||||
* The `window` object is not reset
|
||||
* after each test, so we need to do
|
||||
* that manually otherwise tests will
|
||||
* interefere with each other
|
||||
*/
|
||||
|
||||
let sharedWindow;
|
||||
beforeEach(() => {
|
||||
sharedWindow = Object.create(window);
|
||||
});
|
||||
|
||||
describe('Platform Tests', () => {
|
||||
describe('testUserAgent()', () => {
|
||||
it('should return true when testing if user agent is an iPhone', () => {
|
||||
configureBrowser(sharedWindow, PlatformConfiguration.iPhone);
|
||||
expect(testUserAgent(sharedWindow, /iPhone/)).toEqual(true);
|
||||
const win = configureBrowser(PlatformConfiguration.iPhone);
|
||||
expect(testUserAgent(win, /iPhone/)).toEqual(true);
|
||||
})
|
||||
|
||||
it('should return false when testing if user agent is an iPad', () => {
|
||||
configureBrowser(sharedWindow, PlatformConfiguration.iPhone);
|
||||
expect(testUserAgent(sharedWindow, /iPad/)).toEqual(false);
|
||||
const win = configureBrowser(PlatformConfiguration.iPhone);
|
||||
expect(testUserAgent(win, /iPad/)).toEqual(false);
|
||||
})
|
||||
|
||||
it('should return false when testing if user agent is an Android', () => {
|
||||
configureBrowser(sharedWindow, PlatformConfiguration.iPhone);
|
||||
expect(testUserAgent(sharedWindow, /android|sink/i)).toEqual(false);
|
||||
const win = configureBrowser(PlatformConfiguration.iPhone);
|
||||
expect(testUserAgent(win, /android|sink/i)).toEqual(false);
|
||||
})
|
||||
|
||||
it('should return true when testing if user agent is an Android', () => {
|
||||
configureBrowser(sharedWindow, PlatformConfiguration.AndroidTablet);
|
||||
expect(testUserAgent(sharedWindow, /android|sink/i)).toEqual(true);
|
||||
const win = configureBrowser(PlatformConfiguration.AndroidTablet);
|
||||
expect(testUserAgent(win, /android|sink/i)).toEqual(true);
|
||||
})
|
||||
});
|
||||
|
||||
describe('getPlatforms()', () => {
|
||||
it('should contain "desktop" platform', () => {
|
||||
configureBrowser(sharedWindow, PlatformConfiguration.DesktopSafari);
|
||||
expect(getPlatforms(sharedWindow)).toContain('desktop');
|
||||
const win = configureBrowser(PlatformConfiguration.DesktopSafari);
|
||||
expect(getPlatforms(win)).toContain('desktop');
|
||||
});
|
||||
|
||||
it('should contain "android" and "tablet" platforms', () => {
|
||||
configureBrowser(sharedWindow, PlatformConfiguration.AndroidTablet);
|
||||
const win = configureBrowser(PlatformConfiguration.AndroidTablet);
|
||||
|
||||
const platforms = getPlatforms(sharedWindow);
|
||||
const platforms = getPlatforms(win);
|
||||
expect(platforms).toContain('android');
|
||||
expect(platforms).toContain('tablet');
|
||||
})
|
||||
|
||||
it('should contain "capacitor" platform', () => {
|
||||
configureBrowser(sharedWindow, PlatformConfiguration.Capacitor);
|
||||
expect(getPlatforms(sharedWindow)).toContain('capacitor');
|
||||
const win = configureBrowser(PlatformConfiguration.Capacitor);
|
||||
expect(getPlatforms(win)).toContain('capacitor');
|
||||
})
|
||||
});
|
||||
|
||||
describe('isPlatform()', () => {
|
||||
it('should return true for "capacitor" and "hybrid" in a Capacitor app', () => {
|
||||
configureBrowser(sharedWindow, PlatformConfiguration.Capacitor);
|
||||
expect(isPlatform(sharedWindow, 'capacitor')).toEqual(true);
|
||||
expect(isPlatform(sharedWindow, 'hybrid')).toEqual(true);
|
||||
const win = configureBrowser(PlatformConfiguration.Capacitor);
|
||||
expect(isPlatform(win, 'capacitor')).toEqual(true);
|
||||
expect(isPlatform(win, 'hybrid')).toEqual(true);
|
||||
});
|
||||
|
||||
it('should return false for "capacitor" on desktop safari', () => {
|
||||
configureBrowser(sharedWindow, PlatformConfiguration.DesktopSafari);
|
||||
expect(isPlatform(sharedWindow, 'capacitor')).toEqual(false);
|
||||
it('should return false for "capacitor" and true for "desktop" on desktop safari', () => {
|
||||
const win = configureBrowser(PlatformConfiguration.DesktopSafari);
|
||||
expect(isPlatform(win, 'capacitor')).toEqual(false);
|
||||
expect(isPlatform(win, 'desktop')).toEqual(true);
|
||||
});
|
||||
|
||||
it('should return true for "android" and "tablet" on an android tablet', () => {
|
||||
configureBrowser(sharedWindow, PlatformConfiguration.AndroidTablet);
|
||||
expect(isPlatform(sharedWindow, 'android')).toEqual(true);
|
||||
expect(isPlatform(sharedWindow, 'tablet')).toEqual(true);
|
||||
const win = configureBrowser(PlatformConfiguration.AndroidTablet);
|
||||
expect(isPlatform(win, 'android')).toEqual(true);
|
||||
expect(isPlatform(win, 'tablet')).toEqual(true);
|
||||
});
|
||||
|
||||
it('should return true for "cordova" and "hybrid" in a Cordova app', () => {
|
||||
configureBrowser(sharedWindow, PlatformConfiguration.Cordova);
|
||||
expect(isPlatform(sharedWindow, 'cordova')).toEqual(true);
|
||||
expect(isPlatform(sharedWindow, 'hybrid')).toEqual(true);
|
||||
const win = configureBrowser(PlatformConfiguration.Cordova);
|
||||
expect(isPlatform(win, 'cordova')).toEqual(true);
|
||||
expect(isPlatform(win, 'hybrid')).toEqual(true);
|
||||
});
|
||||
|
||||
it('should return true for "ipad" and "tablet" on an iPad Pro', () => {
|
||||
const win = configureBrowser(PlatformConfiguration.iPadPro);
|
||||
expect(isPlatform(win, 'ipad')).toEqual(true);
|
||||
expect(isPlatform(win, 'tablet')).toEqual(true);
|
||||
});
|
||||
|
||||
it('should return true for "android", false for "tablet, and false for "desktop"" on a Pixel 2 XL', () => {
|
||||
const win = configureBrowser(PlatformConfiguration.Pixel2XL);
|
||||
expect(isPlatform(win, 'android')).toEqual(true);
|
||||
expect(isPlatform(win, 'tablet')).toEqual(false);
|
||||
expect(isPlatform(win, 'desktop')).toEqual(false);
|
||||
});
|
||||
|
||||
it('should return true for "android" and "tablet" and false for "desktop" on a Galaxy View', () => {
|
||||
const win = configureBrowser(PlatformConfiguration.GalaxyView);
|
||||
expect(isPlatform(win, 'android')).toEqual(true);
|
||||
expect(isPlatform(win, 'tablet')).toEqual(true);
|
||||
expect(isPlatform(win, 'desktop')).toEqual(false);
|
||||
});
|
||||
|
||||
it('should return false for "android" and "tablet" on desktop Safari', () => {
|
||||
const win = configureBrowser(PlatformConfiguration.DesktopSafari);
|
||||
expect(isPlatform(win, 'android')).toEqual(false);
|
||||
expect(isPlatform(win, 'tablet')).toEqual(false);
|
||||
});
|
||||
|
||||
it('should return false for "android" and "tablet" and false for "desktop" on iPhone', () => {
|
||||
const win = configureBrowser(PlatformConfiguration.iPhone);
|
||||
expect(isPlatform(win, 'android')).toEqual(false);
|
||||
expect(isPlatform(win, 'tablet')).toEqual(false);
|
||||
expect(isPlatform(win, 'desktop')).toEqual(false);
|
||||
});
|
||||
|
||||
it('should return true for "android", false for "tablet", and false for "desktop" on Galaxy S9 Plus', () => {
|
||||
const win = configureBrowser(PlatformConfiguration.GalaxyS9Plus);
|
||||
expect(isPlatform(win, 'android')).toEqual(true);
|
||||
expect(isPlatform(win, 'tablet')).toEqual(false);
|
||||
expect(isPlatform(win, 'desktop')).toEqual(false);
|
||||
});
|
||||
|
||||
it('should return true for "pwa" and false for "cordova"', () => {
|
||||
const win = configureBrowser(PlatformConfiguration.PWA);
|
||||
expect(isPlatform(win, 'pwa')).toEqual(true);
|
||||
expect(isPlatform(win, 'cordova')).toEqual(false);
|
||||
});
|
||||
|
||||
})
|
||||
});
|
||||
|
||||
function configureBrowser(win: Window, config: PlatformConfiguration): void {
|
||||
for (let attributeKey in config) {
|
||||
win[attributeKey] = config[attributeKey];
|
||||
}
|
||||
}
|
||||
});
|
||||
89
core/src/utils/test/platform.utils.ts
Normal file
89
core/src/utils/test/platform.utils.ts
Normal file
@ -0,0 +1,89 @@
|
||||
export const configureBrowser = (config: any, win: any = Object.create(window)) => {
|
||||
for (const attributeKey in config) {
|
||||
if (config.hasOwnProperty(attributeKey)) {
|
||||
win[attributeKey] = config[attributeKey];
|
||||
}
|
||||
}
|
||||
|
||||
return win;
|
||||
};
|
||||
|
||||
export const mockMatchMedia = (media: string[] = []) => {
|
||||
return jest.fn().mockImplementation(query => {
|
||||
return {
|
||||
matches: media.includes(query)
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export const PlatformConfiguration = {
|
||||
AndroidTablet: {
|
||||
navigator: {
|
||||
userAgent: 'Mozilla/5.0 (Linux; Android 7.0; Pixel C Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/52.0.2743.98 Safari/537.36'
|
||||
},
|
||||
innerWidth: 800,
|
||||
innerHeight: 1200,
|
||||
matchMedia: mockMatchMedia(['(any-pointer:coarse)'])
|
||||
},
|
||||
Capacitor: {
|
||||
Capacitor: {
|
||||
isNative: true
|
||||
}
|
||||
},
|
||||
PWA: {
|
||||
navigator: {
|
||||
standalone: true
|
||||
},
|
||||
matchMedia: mockMatchMedia(['(display-mode: standalone)'])
|
||||
},
|
||||
Cordova: {
|
||||
cordova: true
|
||||
},
|
||||
DesktopSafari: {
|
||||
navigator: {
|
||||
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9'
|
||||
},
|
||||
innerWidth: 1920,
|
||||
innerHeight: 1080
|
||||
},
|
||||
iPhone: {
|
||||
navigator: {
|
||||
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1'
|
||||
},
|
||||
innerWidth: 375,
|
||||
innerHeight: 812,
|
||||
matchMedia: mockMatchMedia(['(any-pointer:coarse)'])
|
||||
},
|
||||
iPadPro: {
|
||||
navigator: {
|
||||
userAgent: 'Mozilla/5.0 (iPad; CPU OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1'
|
||||
},
|
||||
innerWidth: 1024,
|
||||
innerHeight: 1366,
|
||||
matchMedia: mockMatchMedia(['(any-pointer:coarse)'])
|
||||
},
|
||||
Pixel2XL: {
|
||||
navigator: {
|
||||
userAgent: 'Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Mobile Safari/537.36'
|
||||
},
|
||||
innerWidth: 411,
|
||||
innerHeight: 823,
|
||||
matchMedia: mockMatchMedia(['(any-pointer:coarse)'])
|
||||
},
|
||||
GalaxyView: {
|
||||
navigator: {
|
||||
userAgent: 'Mozilla/5.0 (Linux; Android 5.1.1; SM-T670 Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'
|
||||
},
|
||||
innerWidth: 1920,
|
||||
innerHeight: 1080,
|
||||
matchMedia: mockMatchMedia(['(any-pointer:coarse)'])
|
||||
},
|
||||
GalaxyS9Plus: {
|
||||
navigator: {
|
||||
userAgent: 'Mozilla/5.0 (Linux; Android 8.0.0; SM-G965F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.109 Mobile Safari/537.36'
|
||||
},
|
||||
innerWidth: 360,
|
||||
innerHeight: 740,
|
||||
matchMedia: mockMatchMedia(['(any-pointer:coarse)'])
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user