UNPKG

appium-xcuitest-driver

Version:

Appium driver for iOS using XCUITest for backend

354 lines 17.6 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 lodash_1 = __importDefault(require("lodash")); const bluebird_1 = __importDefault(require("bluebird")); const asyncbox_1 = require("asyncbox"); const desired_1 = require("../desired"); const session_1 = require("../helpers/session"); const support_1 = require("appium/support"); 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 - elements -', 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('text', function () { it('should get the text of an element', async function () { const el = await driver.$('~Buttons'); const text = await el.getText(); (0, chai_1.expect)(text).to.eql('Buttons'); }); it('should not mix up elements', async function () { const el1 = await driver.$('~Buttons'); const text1 = await el1.getText(); (0, chai_1.expect)(text1).to.eql('Buttons'); const el2 = await driver.$('~Image View'); const text2 = await el2.getText(); (0, chai_1.expect)(text2).to.eql('Image View'); }); }); describe('name', function () { it('should get the name of an element', async function () { const el = await driver.$('~Buttons'); const name = await el.getTagName(); (0, chai_1.expect)(name).to.eql('XCUIElementTypeStaticText'); }); }); describe('displayed', function () { it('should get the displayed status for a displayed element', async function () { const el = await driver.$('~Buttons'); (0, chai_1.expect)(await el.isDisplayed()).to.be.true; }); it('should get the displayed status for an undisplayed element', async function () { // this value is invisible in the view const el = await driver.$('~Horizontal scroll bar, 1 page'); (0, chai_1.expect)(await el.isDisplayed()).to.be.false; }); }); describe('location', function () { it('should get the location of an element', async function () { const el = await driver.$('~Buttons'); const loc = await el.getLocation(); (0, chai_1.expect)(loc.x).to.exist; (0, chai_1.expect)(loc.y).to.exist; }); it('should not mix up locations', async function () { const el1 = await driver.$('~Date Picker'); const loc1 = await el1.getLocation(); const el2 = await driver.$('~Image View'); const loc2 = await el2.getLocation(); (0, chai_1.expect)(loc1.x).to.eql(loc2.x); (0, chai_1.expect)(loc1.y).to.be.below(loc2.y); }); }); describe('location_in_view', function () { it('should get the location of an element', async function () { const el = await driver.$('~Buttons'); const loc = await el.getLocation(); (0, chai_1.expect)(loc.x).to.exist; (0, chai_1.expect)(loc.y).to.exist; }); it('should not mix up locations', async function () { const el1 = await driver.$('~Date Picker'); const loc1 = await el1.getLocation(); const el2 = await driver.$('~Image View'); const loc2 = await el2.getLocation(); (0, chai_1.expect)(loc1.x).to.eql(loc2.x); (0, chai_1.expect)(loc1.y).to.be.below(loc2.y); }); }); describe('size', function () { it('should get the size of the element', async function () { const el = await driver.$('~Buttons'); const size = await el.getSize(); (0, chai_1.expect)(size.width).to.exist; (0, chai_1.expect)(size.height).to.exist; }); }); describe('contentSize', function () { it('should get the contentSize of a table', async function () { const uiCatalogCaps = await (0, desired_1.getUICatalogCaps)(); if (support_1.util.compareVersions((0, desired_1.extractCapabilityValue)(uiCatalogCaps, 'appium:platformVersion'), '>=', '13.0')) { return this.skip(); } const table = await driver.$('XCUIElementTypeTable'); const contentSize = JSON.parse(await table.getAttribute('contentSize')); (0, chai_1.expect)(contentSize.width).to.be.a('number'); (0, chai_1.expect)(contentSize.height).to.be.a('number'); (0, chai_1.expect)(contentSize.top).to.be.a('number'); (0, chai_1.expect)(contentSize.left).to.be.a('number'); (0, chai_1.expect)(contentSize.scrollableOffset).to.be.a('number'); (0, chai_1.expect)(contentSize.height).to.be.above(500); // basically, the height of the inner content should be at least 200 // pixels more than the height of the container (0, chai_1.expect)(contentSize.scrollableOffset).to.be.above(contentSize.height + 200); }); it.skip('should get the contentSize of a collection view', async function () { // TODO UICatalog doesn't seem to have collection views I could find }); it('should not get the contentSize of other kinds of elements', async function () { let wrongTypeEl = await driver.$('~UIKitCatalog'); if (wrongTypeEl.error) { wrongTypeEl = await driver.$('~UICatalog'); } await (0, chai_1.expect)(wrongTypeEl.getAttribute('contentSize')).to.eventually.be.rejectedWith(/Can't get content size for type/); }); }); describe('touch click', function () { it('should click an element', async function () { await (0, asyncbox_1.retryInterval)(10, 500, async function () { const el = await driver.$('~Buttons'); await el.click(); await bluebird_1.default.delay(1000); (0, chai_1.expect)(await driver.$$('XCUIElementTypeButton')).to.have.length.above(4); await driver.back(); }); }); }); describe('interactions', function () { this.retries(2); describe('text fields', function () { const text1 = 'bunchoftext'; const text2 = 'differenttext'; const text3 = 'http://appium.io/'; const secureText = lodash_1.default.map(new Array(text1.length), () => '•').join(''); const phText = 'Placeholder text'; beforeEach(async function () { const el = await (0, asyncbox_1.retryInterval)(10, 500, async function () { return await driver.$('~Text Fields'); }); await driver.execute('mobile: scroll', { element: el.elementId, toVisible: true }); await el.click(); }); afterEach(async function () { await driver.back(); }); describe('set value', function () { it('should type in the text field', async function () { const el = await driver.$('XCUIElementTypeTextField'); await el.setValue(text1); const text = await el.getText(); (0, chai_1.expect)(text).to.eql(text1); }); it('should type in the text field even before the keyboard is up', async function () { const el = await driver.$('XCUIElementTypeTextField'); await el.setValue(text1); const text = await el.getText(); (0, chai_1.expect)(text).to.eql(text1); }); it('should type a url in the text field', async function () { // in Travis this sometimes gets the wrong text const retries = process.env.CI ? 5 : 1; await (0, asyncbox_1.retryInterval)(retries, 100, async () => { const el = await driver.$('XCUIElementTypeTextField'); await el.clearValue(); await el.setValue(text3); const text = await el.getText(); (0, chai_1.expect)(text).to.eql(text3); }); }); it('should be able to type into two text fields', async function () { const els = await driver.$$('XCUIElementTypeTextField'); await els[0].setValue(text1); await driver.hideKeyboard(); await els[1].setValue(text2); let text = await els[0].getText(); (0, chai_1.expect)(text).to.eql(text1); text = await els[1].getText(); (0, chai_1.expect)(text).to.eql(text2); }); it('should type in a secure text field', async function () { const els = await driver.$$('XCUIElementTypeSecureTextField'); await els[0].setValue(text1); const text = await els[0].getText(); (0, chai_1.expect)(text).to.not.eql(text1); (0, chai_1.expect)(text.length).to.eql(text1.length); (0, chai_1.expect)(text).to.eql(secureText); }); it('should type a backspace', async function () { const el = await driver.$('XCUIElementTypeTextField'); await driver.elementSendKeys(el.elementId, '0123456789\uE003'); const text = await el.getText(); (0, chai_1.expect)(text).to.eql('012345678'); }); it('should type a delete', async function () { const el = await driver.$('XCUIElementTypeTextField'); await driver.elementSendKeys(el.elementId, '0123456789\ue017'); const text = await el.getText(); (0, chai_1.expect)(text).to.eql('012345678'); }); it('should type a newline', async function () { const el = await driver.$('XCUIElementTypeTextField'); await driver.elementSendKeys(el.elementId, '0123456789\uE006'); const text = await el.getText(); (0, chai_1.expect)(text).to.eql('0123456789'); }); }); describe('clear', function () { it('should clear a text field', async function () { const text1 = '0123456789abcdefghijklmnopqrstuvwxyz'; const el = await driver.$('XCUIElementTypeTextField'); await el.setValue(text1); let text = await el.getText(); (0, chai_1.expect)(text).to.eql(text1); await el.clearValue(); text = await el.getText(); (0, chai_1.expect)(text).to.eql(phText); }); it('should be able to clear two text fields', async function () { const els = await driver.$$('XCUIElementTypeTextField'); await els[0].setValue(text1); let text = await els[0].getText(); (0, chai_1.expect)(text).to.eql(text1); await driver.hideKeyboard(); await els[1].setValue(text2); text = await els[1].getText(); (0, chai_1.expect)(text).to.eql(text2); await els[0].clearValue(); text = await els[0].getText(); (0, chai_1.expect)(text).to.eql(phText); await driver.hideKeyboard(); await els[1].clearValue(); text = await els[1].getText(); (0, chai_1.expect)(text).to.eql(phText); }); it('should clear a secure text field', async function () { const el = await driver.$('XCUIElementTypeSecureTextField'); await el.setValue(text1); let text = await el.getText(); (0, chai_1.expect)(text).to.eql(secureText); await el.clearValue(); text = await el.getText(); (0, chai_1.expect)(text).to.eql(phText); }); }); describe('key', function () { it('should be able to send text to the active element', async function () { const el = await driver.$('XCUIElementTypeTextField'); // make sure the keyboard is up await el.click(); const actions = [ // Selenium clients generate below code for `driver.action.send_keys('a').perform`. { type: 'pointer', id: 'touch', actions: [ { type: 'pause', duration: 0 }, { type: 'pause', duration: 0 }, { type: 'pause', duration: 0 }, { type: 'pause', duration: 0 }, { type: 'pause', duration: 0 }, { type: 'pause', duration: 0 } ] }, { type: 'key', id: 'keyboard', actions: [ { type: 'keyDown', value: 'h' }, { type: 'keyUp', value: 'h' }, { type: 'keyDown', value: 'i' }, { type: 'keyUp', value: 'i' }, { type: 'keyDown', value: 'あ' }, { type: 'keyUp', value: 'あ' }, ], }, ]; await driver.performActions(actions); const text = await el.getText(); (0, chai_1.expect)(text).to.eql('hiあ'); }); }); describe('hide keyboard', function () { it('should pass if the keyboard is already hidden', async function () { await (0, chai_1.expect)(driver.hideKeyboard()).to.be.fulfilled; }); }); }); describe('picker wheel', function () { beforeEach(async function () { const el = await driver.$('~Picker View'); await el.click(); }); afterEach(async function () { await driver.back(); }); it('should be able to set the value', async function () { const wheels = await driver.$$('XCUIElementTypePickerWheel'); const values = [65, 205, 120]; for (let i = 0; i < 3; i++) { const wheel = wheels[i]; let value = await wheel.getAttribute('value'); (0, chai_1.expect)(parseInt(value, 10)).to.eql(values[i]); await wheel.setValue(150); value = await wheel.getAttribute('value'); (0, chai_1.expect)(parseInt(value, 10)).to.eql(150); } }); }); }); }); //# sourceMappingURL=element-e2e-specs.js.map