appium-xcuitest-driver
Version:
Appium driver for iOS using XCUITest for backend
354 lines • 17.6 kB
JavaScript
;
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