mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-08 07:41:51 +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) =>
|
const isAndroid = (win: Window) =>
|
||||||
testUserAgent(win, /android|sink/i);
|
testUserAgent(win, /android|sink/i);
|
||||||
|
|
||||||
|
const isAndroidTablet = (win: Window) => {
|
||||||
|
return isAndroid(win) && !testUserAgent(win, /mobile/i);
|
||||||
|
};
|
||||||
|
|
||||||
const isPhablet = (win: Window) => {
|
const isPhablet = (win: Window) => {
|
||||||
const width = win.innerWidth;
|
const width = win.innerWidth;
|
||||||
const height = win.innerHeight;
|
const height = win.innerHeight;
|
||||||
@ -50,8 +54,15 @@ const isTablet = (win: Window) => {
|
|||||||
const height = win.innerHeight;
|
const height = win.innerHeight;
|
||||||
const smallest = Math.min(width, height);
|
const smallest = Math.min(width, height);
|
||||||
const largest = Math.max(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) =>
|
const isMobile = (win: Window) =>
|
||||||
|
|||||||
@ -1,121 +1,118 @@
|
|||||||
import { testUserAgent, getPlatforms, isPlatform } from '../platform';
|
import { testUserAgent, getPlatforms, isPlatform } from '../platform';
|
||||||
|
import { PlatformConfiguration, configureBrowser } from './platform.utils';
|
||||||
|
|
||||||
enum PlatformConfiguration {
|
describe('Platform Tests', () => {
|
||||||
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('testUserAgent()', () => {
|
describe('testUserAgent()', () => {
|
||||||
it('should return true when testing if user agent is an iPhone', () => {
|
it('should return true when testing if user agent is an iPhone', () => {
|
||||||
configureBrowser(sharedWindow, PlatformConfiguration.iPhone);
|
const win = configureBrowser(PlatformConfiguration.iPhone);
|
||||||
expect(testUserAgent(sharedWindow, /iPhone/)).toEqual(true);
|
expect(testUserAgent(win, /iPhone/)).toEqual(true);
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return false when testing if user agent is an iPad', () => {
|
it('should return false when testing if user agent is an iPad', () => {
|
||||||
configureBrowser(sharedWindow, PlatformConfiguration.iPhone);
|
const win = configureBrowser(PlatformConfiguration.iPhone);
|
||||||
expect(testUserAgent(sharedWindow, /iPad/)).toEqual(false);
|
expect(testUserAgent(win, /iPad/)).toEqual(false);
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return false when testing if user agent is an Android', () => {
|
it('should return false when testing if user agent is an Android', () => {
|
||||||
configureBrowser(sharedWindow, PlatformConfiguration.iPhone);
|
const win = configureBrowser(PlatformConfiguration.iPhone);
|
||||||
expect(testUserAgent(sharedWindow, /android|sink/i)).toEqual(false);
|
expect(testUserAgent(win, /android|sink/i)).toEqual(false);
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return true when testing if user agent is an Android', () => {
|
it('should return true when testing if user agent is an Android', () => {
|
||||||
configureBrowser(sharedWindow, PlatformConfiguration.AndroidTablet);
|
const win = configureBrowser(PlatformConfiguration.AndroidTablet);
|
||||||
expect(testUserAgent(sharedWindow, /android|sink/i)).toEqual(true);
|
expect(testUserAgent(win, /android|sink/i)).toEqual(true);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getPlatforms()', () => {
|
describe('getPlatforms()', () => {
|
||||||
it('should contain "desktop" platform', () => {
|
it('should contain "desktop" platform', () => {
|
||||||
configureBrowser(sharedWindow, PlatformConfiguration.DesktopSafari);
|
const win = configureBrowser(PlatformConfiguration.DesktopSafari);
|
||||||
expect(getPlatforms(sharedWindow)).toContain('desktop');
|
expect(getPlatforms(win)).toContain('desktop');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should contain "android" and "tablet" platforms', () => {
|
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('android');
|
||||||
expect(platforms).toContain('tablet');
|
expect(platforms).toContain('tablet');
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should contain "capacitor" platform', () => {
|
it('should contain "capacitor" platform', () => {
|
||||||
configureBrowser(sharedWindow, PlatformConfiguration.Capacitor);
|
const win = configureBrowser(PlatformConfiguration.Capacitor);
|
||||||
expect(getPlatforms(sharedWindow)).toContain('capacitor');
|
expect(getPlatforms(win)).toContain('capacitor');
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isPlatform()', () => {
|
describe('isPlatform()', () => {
|
||||||
it('should return true for "capacitor" and "hybrid" in a Capacitor app', () => {
|
it('should return true for "capacitor" and "hybrid" in a Capacitor app', () => {
|
||||||
configureBrowser(sharedWindow, PlatformConfiguration.Capacitor);
|
const win = configureBrowser(PlatformConfiguration.Capacitor);
|
||||||
expect(isPlatform(sharedWindow, 'capacitor')).toEqual(true);
|
expect(isPlatform(win, 'capacitor')).toEqual(true);
|
||||||
expect(isPlatform(sharedWindow, 'hybrid')).toEqual(true);
|
expect(isPlatform(win, 'hybrid')).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false for "capacitor" on desktop safari', () => {
|
it('should return false for "capacitor" and true for "desktop" on desktop safari', () => {
|
||||||
configureBrowser(sharedWindow, PlatformConfiguration.DesktopSafari);
|
const win = configureBrowser(PlatformConfiguration.DesktopSafari);
|
||||||
expect(isPlatform(sharedWindow, 'capacitor')).toEqual(false);
|
expect(isPlatform(win, 'capacitor')).toEqual(false);
|
||||||
|
expect(isPlatform(win, 'desktop')).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true for "android" and "tablet" on an android tablet', () => {
|
it('should return true for "android" and "tablet" on an android tablet', () => {
|
||||||
configureBrowser(sharedWindow, PlatformConfiguration.AndroidTablet);
|
const win = configureBrowser(PlatformConfiguration.AndroidTablet);
|
||||||
expect(isPlatform(sharedWindow, 'android')).toEqual(true);
|
expect(isPlatform(win, 'android')).toEqual(true);
|
||||||
expect(isPlatform(sharedWindow, 'tablet')).toEqual(true);
|
expect(isPlatform(win, 'tablet')).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true for "cordova" and "hybrid" in a Cordova app', () => {
|
it('should return true for "cordova" and "hybrid" in a Cordova app', () => {
|
||||||
configureBrowser(sharedWindow, PlatformConfiguration.Cordova);
|
const win = configureBrowser(PlatformConfiguration.Cordova);
|
||||||
expect(isPlatform(sharedWindow, 'cordova')).toEqual(true);
|
expect(isPlatform(win, 'cordova')).toEqual(true);
|
||||||
expect(isPlatform(sharedWindow, 'hybrid')).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