UNPKG

appium-xcuitest-driver

Version:

Appium driver for iOS using XCUITest for backend

268 lines 12.5 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const bluebird_1 = __importDefault(require("bluebird")); const util_1 = __importDefault(require("util")); const asyncbox_1 = require("asyncbox"); const desired_1 = require("../desired"); const session_1 = require("../helpers/session"); const helpers_1 = require("../web/helpers"); const sharp_1 = __importDefault(require("sharp")); const chai_1 = __importStar(require("chai")); const chai_as_promised_1 = __importDefault(require("chai-as-promised")); chai_1.default.use(chai_as_promised_1.default); describe('XCUITestDriver - basics -', function () { this.timeout(session_1.MOCHA_TIMEOUT); let driver; before(async function () { const uiCatalogCaps = await (0, desired_1.getUICatalogCaps)(); driver = await (0, session_1.initSession)(uiCatalogCaps); }); after(async function () { await (0, session_1.deleteSession)(); }); describe('status -', function () { it('should get the server status', async function () { const status = await driver.status(); (0, chai_1.expect)(status.build.version).to.exist; }); it('should return status immediately if another operation is in progress', async function () { await driver.setTimeout({ implicit: 10000 }); const findElementPromise = driver.$('#WrongLocator'); const status = await driver.status(); (0, chai_1.expect)(status.build.version).to.exist; (0, chai_1.expect)(util_1.default.inspect(findElementPromise).includes('pending')).to.be.true; try { await findElementPromise; } catch (err) { (0, chai_1.expect)(err.status).to.eql(7); } }); }); describe('source -', function () { function checkSource(src) { // should have full elements (0, chai_1.expect)(src).to.include('<AppiumAUT>'); (0, chai_1.expect)(src).to.include('<XCUIElementTypeApplication'); // should not have any XCTest errors (0, chai_1.expect)(src).to.not.include('AX error'); } describe('plain -', function () { it('should get the source for the page', async function () { const src = await driver.getPageSource(); (0, chai_1.expect)(typeof src).to.eql('string'); checkSource(src); }); }); describe('json parsed -', function () { it('should get source with useJSONSource', async function () { await driver.updateSettings({ useJSONSource: true }); const src = await driver.getPageSource(); checkSource(src); }); }); }); describe('deactivate app -', function () { it('should background the app for the specified time', async function () { const before = Date.now(); await driver.background(4); (0, chai_1.expect)(Date.now() - before).to.be.above(4000); (0, chai_1.expect)((await driver.getPageSource()).indexOf('<AppiumAUT>')).to.not.eql(-1); }); }); describe('screenshot -', function () { after(async function () { try { await driver.setOrientation('PORTRAIT'); } catch { } }); it('should get an app screenshot', async function () { const screenshot = await driver.takeScreenshot(); (0, chai_1.expect)(screenshot).to.exist; (0, chai_1.expect)(screenshot).to.be.a('string'); // make sure WDA didn't crash, by using it again const els = await driver.$$('~Alert Views'); (0, chai_1.expect)(els.length).to.eql(1); }); it('should get an app screenshot in landscape mode', async function () { const screenshot1 = await driver.takeScreenshot(); (0, chai_1.expect)(screenshot1).to.exist; try { await driver.setOrientation('LANDSCAPE'); } catch { } // take a little pause while it orients, otherwise you get the screenshot // on an angle await bluebird_1.default.delay(500); const screenshot2 = await driver.takeScreenshot(); (0, chai_1.expect)(screenshot2).to.exist; (0, chai_1.expect)(screenshot2).to.not.eql(screenshot1); }); }); describe('viewportScreenshot -', function () { it('should get a cropped screenshot of the viewport without statusbar', async function () { if (process.env.CI) { // Skip on GHA. Local had no issue but GHA had failed in 'mobile: viewportScreenshot'. return this.skip(); } const { statusBarSize, scale } = await driver.execute('mobile: deviceScreenInfo'); const viewportRect = await driver.execute('mobile: viewportRect'); const fullScreen = await driver.takeScreenshot(); const viewScreen = await driver.execute('mobile: viewportScreenshot'); const fullImg = (0, sharp_1.default)(Buffer.from(fullScreen, 'base64')); const { width: fullImgWidth, height: fullImgHeight } = await fullImg.metadata(); const viewImg = (0, sharp_1.default)(Buffer.from(viewScreen, 'base64')); const { width: viewImgWidth, height: viewImgHeight } = await viewImg.metadata(); if (fullImgWidth === undefined || fullImgHeight === undefined || viewImgWidth === undefined || viewImgHeight === undefined) { throw new Error('Image dimensions must not be undefined'); } // Viewport size can be smaller than the full image size + status bar on some devices. (0, chai_1.expect)(fullImgHeight).to.be.gte(viewImgHeight + Math.round(scale * statusBarSize.height)); (0, chai_1.expect)(viewImgHeight).to.eql(viewportRect.height); (0, chai_1.expect)(fullImgWidth).to.be.gte(viewImgWidth); }); }); describe('logging -', function () { describe('types -', function () { it('should get the list of available logs', async function () { const actualTypes = await driver.getLogTypes(); for (const expectedType of ['syslog', 'crashlog', 'performance', 'safariConsole', 'safariNetwork', 'server']) { (0, chai_1.expect)(actualTypes).to.include(expectedType); } }); }); describe('retrieval -', function () { it('should throw an error when an invalid type is given', async function () { await (0, chai_1.expect)(driver.getLogs('something-random')).to.be.rejected; }); it('should get system logs', async function () { (0, chai_1.expect)(await driver.getLogs('syslog')).to.be.an('array'); }); it('should get crash logs', async function () { (0, chai_1.expect)(await driver.getLogs('crashlog')).to.be.an('array'); }); }); }); describe('orientation -', function () { beforeEach(async function () { await driver.setOrientation('PORTRAIT'); }); afterEach(async function () { await driver.setOrientation('PORTRAIT'); }); it('should get the current orientation', async function () { const orientation = await driver.getOrientation(); (0, chai_1.expect)(['PORTRAIT', 'LANDSCAPE']).to.include(orientation); }); it('should set the orientation', async function () { await driver.setOrientation('LANDSCAPE'); (0, chai_1.expect)(await driver.getOrientation()).to.eql('LANDSCAPE'); }); it('should be able to interact with an element in LANDSCAPE', async function () { await driver.setOrientation('LANDSCAPE'); const el = await driver.$('#Buttons'); await el.click(); await (0, chai_1.expect)(driver.findElement('css selector', '#Button')).to.not.be.rejected; await driver.back(); }); }); describe('window size -', function () { it('should be able to get the current window size', async function () { const size = await driver.getWindowRect(); (0, chai_1.expect)(size.width).to.be.a('number'); (0, chai_1.expect)(size.height).to.be.a('number'); }); }); describe('geo location -', function () { it('should work on Simulator', async function () { await (0, chai_1.expect)(driver.execute('mobile: getSimulatedLocation')).to.be.fulfilled; await (0, chai_1.expect)(driver.execute('mobile: setSimulatedLocation', { latitude: '30.0001', longitude: '21.0002' })).to.not.be .rejected; }); }); describe('shake -', function () { it('should work on Simulator', async function () { await (0, chai_1.expect)(driver.execute('mobile: shake')).to.be.fulfilled; }); }); describe('lock -', function () { it('should properly lock and unlock the device', async function () { try { await driver.lock(); (0, chai_1.expect)(await driver.isLocked()).to.be.true; } finally { await driver.unlock(); } (0, chai_1.expect)(await driver.isLocked()).to.be.false; }); }); describe('contexts -', function () { before(async function () { await driver.execute('mobile: scroll', { direction: 'down' }); await driver.$('~Web View').click(); }); after(async function () { await driver.back(); await driver.execute('mobile: scroll', { direction: 'up' }); }); it('should start a session, navigate to url, get title', async function () { if (process.env.CI && (0, desired_1.isIosVersionBelow)('18.0')) { this.skip(); } const contexts = await driver.execute('mobile: getContexts', { waitForWebviewMs: 10000 }); if (process.env.CI && contexts.length < 2) { // Skip on CI, since the simulator may be too slow to fetch a webview context in time return this.skip(); } await driver.switchContext(contexts[1].id); await driver.navigateTo(helpers_1.GUINEA_PIG_PAGE); await (0, asyncbox_1.retryInterval)(100, 1000, async function () { const title = await driver.getTitle(); (0, chai_1.expect)(title).to.equal('I am a page title'); }); await driver.switchContext(contexts[0].id); }); }); }); //# sourceMappingURL=basic-e2e-specs.js.map