taiko
Version:
Taiko is a Node.js library for automating Chromium based browsers
112 lines (98 loc) • 3.08 kB
JavaScript
const { eventHandler } = require("../eventBus");
const networkHandler = require("./networkHandler");
let emulation;
let currentViewportSettings = null;
const createdSessionListener = async (client) => {
let resolve;
eventHandler.emit(
"handlerActingOnNewSession",
new Promise((r) => {
resolve = r;
}),
);
emulation = client.Emulation;
// Reapply viewport settings if they were previously set
if (currentViewportSettings) {
await applyViewportSettings(currentViewportSettings);
}
resolve();
};
eventHandler.on("createdSession", createdSessionListener);
const applyViewportSettings = async (options) => {
const hasTouch = options.hasTouch || false;
await Promise.all([
emulation.setDeviceMetricsOverride(options),
emulation.setTouchEmulationEnabled({ enabled: hasTouch }),
]);
};
const setViewport = async (options) => {
if (options.height === undefined || options.width === undefined) {
throw new Error("No height and width provided");
}
options.mobile = options.mobile || false;
options.deviceScaleFactor = options.deviceScaleFactor || 1;
options.screenOrientation =
options.screenOrientation || options.isLandscape
? { angle: 90, type: "landscapePrimary" }
: { angle: 0, type: "portraitPrimary" };
// Store viewport settings for reapplication when new tabs are created
currentViewportSettings = options;
await applyViewportSettings(options);
};
const setTimeZone = async (timezone) => {
try {
await emulation.setTimezoneOverride({ timezoneId: timezone });
} catch (exception) {
if (exception.message.includes("Invalid timezone")) {
throw new Error(`Invalid timezone ID: ${timezone}`);
}
throw exception;
}
};
const setLocation = async (options) => {
const { longitude, latitude, accuracy = 0 } = options;
if (longitude < -180 || longitude > 180) {
throw new Error(
`Invalid longitude "${longitude}": precondition -180 <= LONGITUDE <= 180 failed.`,
);
}
if (latitude < -90 || latitude > 90) {
throw new Error(
`Invalid latitude "${latitude}": precondition -90 <= LATITUDE <= 90 failed.`,
);
}
if (accuracy < 0) {
throw new Error(
`Invalid accuracy "${accuracy}": precondition 0 <= ACCURACY failed.`,
);
}
await emulation
.setGeolocationOverride({ longitude, latitude, accuracy })
.catch((err) => {
throw new Error(err);
});
};
const emulateDevice = async (deviceModel) => {
const devices = require("../data/devices").default;
const deviceEmulate = devices[deviceModel];
const deviceNames = Object.keys(devices);
if (deviceEmulate === undefined) {
throw new Error(
`Please set one of the given device models \n${deviceNames.join("\n")}`,
);
}
await Promise.all([
setViewport(deviceEmulate.viewport),
networkHandler.setUserAgent(deviceEmulate),
]);
};
const resetViewportSettings = () => {
currentViewportSettings = null;
};
module.exports = {
setLocation,
setViewport,
setTimeZone,
emulateDevice,
resetViewportSettings,
};