Skip to content
Permalink
Browse files

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
  • Loading branch information...
liamdebeasi committed Mar 15, 2019
1 parent f6783db commit 29dbd0770c9d2dfc3e7a53b8b914762f33934427
Showing with 178 additions and 81 deletions.
  1. +13 −2 core/src/utils/platform.ts
  2. +76 −79 core/src/utils/test/platform.spec.ts
  3. +89 −0 core/src/utils/test/platform.utils.ts
@@ -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];
}
}
});
@@ -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)'])
}
};

0 comments on commit 29dbd07

Please sign in to comment.
You can’t perform that action at this time.