UNPKG

asksuite-core

Version:
101 lines (85 loc) 3.19 kB
/* eslint-disable no-extend-native */ /* eslint-disable no-undef */ /* eslint-disable no-proto */ // initial evasions from @sangaline // https://intoli.com/blog/not-possible-to-block-chrome-headless/ // https://intoli.com/blog/not-possible-to-block-chrome-headless/test-headless-final.js module.exports = async function (page) { // Pass the User-Agent Test. const userAgent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'; await page.setUserAgent(userAgent); // Pass the Webdriver Test. await page.evaluateOnNewDocument(() => { Object.defineProperty(navigator, 'webdriver', { get: () => false, }); }); // Pass the Chrome Test. await page.evaluateOnNewDocument(() => { // We can mock this in as much depth as we need for the test. window.chrome = { runtime: {}, }; }); // Pass the Permissions Test. await page.evaluateOnNewDocument(() => { const originalQuery = window.navigator.permissions.query; window.navigator.permissions.__proto__.query = (parameters) => parameters.name === 'notifications' ? Promise.resolve({ state: Notification.permission }) : originalQuery(parameters); // Inspired by: https://github.com/ikarienator/phantomjs_hide_and_seek/blob/master/5.spoofFunctionBind.js const oldCall = Function.prototype.call; function call() { return oldCall.apply(this, arguments); } Function.prototype.call = call; const nativeToStringFunctionString = Error.toString().replace(/Error/g, 'toString'); const oldToString = Function.prototype.toString; function functionToString() { if (this === window.navigator.permissions.query) { return 'function query() { [native code] }'; } if (this === functionToString) { return nativeToStringFunctionString; } return oldCall.call(oldToString, this); } Function.prototype.toString = functionToString; }); // Pass the Plugins Length Test. await page.evaluateOnNewDocument(() => { // Overwrite the `plugins` property to use a custom getter. Object.defineProperty(navigator, 'plugins', { // This just needs to have `length > 0` for the current test, // but we could mock the plugins too if necessary. get: () => [1, 2, 3, 4, 5], }); }); // Pass the Languages Test. await page.evaluateOnNewDocument(() => { // Overwrite the `plugins` property to use a custom getter. Object.defineProperty(navigator, 'languages', { get: () => ['pt-BR', 'pt', 'en-US', 'en', 'es'], }); }); // Pass the iframe Test await page.evaluateOnNewDocument(() => { Object.defineProperty(HTMLIFrameElement.prototype, 'contentWindow', { get: function () { return window; }, }); }); // Pass toString test, though it breaks console.debug() from working await page.evaluateOnNewDocument(() => { window.console.debug = () => { return null; }; }); await page.setExtraHTTPHeaders({ 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7,es;q=0.6', }); };