web2driver
Version:
Pure-JS, browser-based WebDriver (+ Appium) client
275 lines • 21.9 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = __importDefault(require("../index"));
const chai_1 = __importDefault(require("chai"));
const should_1 = __importDefault(require("should"));
chai_1.default.use(should_1.default);
const MOCHA_TIMEOUT = 60000;
const INIT_TIMEOUT = 120000;
const SERVER = "127.0.0.1";
const PORT = 4723;
const OPTS = {
hostname: SERVER,
port: PORT,
path: '/',
connectionRetryCount: 0,
};
const CAPS = {
platformName: "iOS",
browserName: "Safari",
'appium:platformVersion': "16.2",
'appium:deviceName': "iPhone 13",
'appium:automationName': "XCUITest"
};
const TEST_URL = "http://localhost:1234/fixture.html";
if (typeof mocha !== 'undefined') {
mocha.setup({ timeout: MOCHA_TIMEOUT });
}
describe('Web2Driver', function () {
let driver;
before(function () {
return __awaiter(this, void 0, void 0, function* () {
this.timeout(INIT_TIMEOUT);
driver = yield index_1.default.remote(OPTS, CAPS);
yield driver.navigateTo(TEST_URL);
});
});
after(function () {
return __awaiter(this, void 0, void 0, function* () {
yield driver.quit();
});
});
it('should store the session id', function () {
driver.sessionId.should.be.a.string;
});
it('should have capabilities from the session', function () {
driver.capabilities.should.be.a.object;
driver.capabilities.platformName.should.eql('iOS');
});
it('should not be able to use jsonwp commands', function () {
return __awaiter(this, void 0, void 0, function* () {
should_1.default.not.exist(driver.setImplicitWaitTimeout);
});
});
it('should be able to use mjsonwp commands', function () {
return __awaiter(this, void 0, void 0, function* () {
const ctxs = yield driver.getContexts();
ctxs.length.should.be.above(1);
});
});
it('should be able to find elements and do stuff to them', function () {
return __awaiter(this, void 0, void 0, function* () {
const el = yield driver.findElement('id', 'header');
(yield el.getText()).should.eql('This is a header');
});
});
it('should throw errors for not found elements', function () {
return __awaiter(this, void 0, void 0, function* () {
let err;
try {
yield driver.findElement('id', 'notathingatall');
}
catch (_err) {
err = _err;
}
should_1.default.exist(err);
err.message.should.match(/element could not be located/);
});
});
it('should be able to find multiple elements', function () {
return __awaiter(this, void 0, void 0, function* () {
const els = yield driver.findElements('id', 'header');
(yield els[0].getText()).should.eql('This is a header');
});
});
it('should be able to find an element from an element', function () {
return __awaiter(this, void 0, void 0, function* () {
const el = yield driver.findElement('id', 'outerDiv');
const el2 = yield el.findElement('tag name', 'div');
(yield el2.getText()).should.eql('This is an inner div');
});
});
it('should be able to find multiple elements from an element', function () {
return __awaiter(this, void 0, void 0, function* () {
const el = yield driver.findElement('id', 'outerDiv');
const ps = yield el.findElements('tag name', 'p');
const validTexts = ['This is an outer div', 'This is an inner div'];
for (const p of ps) {
validTexts.should.containEql(yield p.getText());
}
});
});
it('should serialize elements for use in executeScript', function () {
return __awaiter(this, void 0, void 0, function* () {
const el = yield driver.findElement('id', 'innerDiv');
const p = yield el.findElement('tag name', 'p');
const res = yield driver.executeScript("return arguments[0].innerHTML;", [p]);
res.should.eql('This is an inner div');
});
});
it('should be able to run w3c actions', function () {
return __awaiter(this, void 0, void 0, function* () {
yield driver.performActions([{
type: 'pointer',
id: 'finger1',
parameters: { pointerType: 'touch' },
actions: [
{ type: 'pointerMove', duration: 0, x: 500, y: 500 },
{ type: 'pointerDown', button: 0 },
{ type: 'pause', duration: 200 },
{ type: 'pointerUp', button: 0 },
]
}]);
});
});
it('should be able to send keys', function () {
return __awaiter(this, void 0, void 0, function* () {
const ctx = yield driver.getContext();
yield driver.switchContext('NATIVE_APP');
try {
let el = yield driver.waitForElement(1000, 'accessibility id', 'TabBarItemTitle');
yield el.click();
el = yield driver.waitForElement(1000, 'accessibility id', 'URL');
(yield el.getText()).should.not.eql('foo');
yield el.sendKeys("foo");
(yield el.getText()).should.eql('foo');
el = yield driver.waitForElement(1000, 'accessibility id', 'CancelBarItemButton');
yield el.click();
}
finally {
yield driver.switchContext(ctx);
}
});
});
it('should respect implicit wait timeout', function () {
return __awaiter(this, void 0, void 0, function* () {
let start = Date.now();
try {
yield driver.findElement('id', 'doesnotexist');
}
catch (ign) { }
(Date.now() - start).should.be.below(1000);
yield driver.setTimeouts(2000);
start = Date.now();
try {
yield driver.findElement('id', 'doesnotexist');
}
catch (ign) { }
(Date.now() - start).should.be.above(1900);
});
});
it('should be able to explicitly wait for an element', function () {
return __awaiter(this, void 0, void 0, function* () {
yield driver.waitForElement(2000, 'id', 'innerDiv');
});
});
it('should throw an error after timeout for explicit wait', function () {
return __awaiter(this, void 0, void 0, function* () {
let start = Date.now();
try {
yield driver.waitForElement(2000, 'id', 'doesnotexist');
}
catch (ign) { }
(Date.now() - start).should.be.above(2000);
});
});
it('should be able to explicitly wait for multiple elements', function () {
return __awaiter(this, void 0, void 0, function* () {
(yield driver.waitForElements(2000, 'id', 'innerDiv')).should.have.length(1);
});
});
it('should throw an error after timeout for explicit wait, even for multiple elements', function () {
return __awaiter(this, void 0, void 0, function* () {
let start = Date.now();
try {
yield driver.waitForElements(2000, 'id', 'doesnotexist');
}
catch (ign) { }
(Date.now() - start).should.be.above(2000);
});
});
it('should be able to attach to an existing session', function () {
return __awaiter(this, void 0, void 0, function* () {
const driver2 = yield index_1.default.attachToSession(driver.sessionId, {
hostname: SERVER,
port: PORT,
path: '/',
});
(yield driver2.getUrl()).should.eql(TEST_URL);
});
});
});
describe('Web2Driver - Auth details', function () {
it('should be able to send auth details without error', function () {
return __awaiter(this, void 0, void 0, function* () {
let err;
const opts = {
connectionRetryCount: 0,
hostname: SERVER,
key: "foo",
path: "/",
port: PORT,
protocol: "http",
user: "user",
};
const caps = {};
try {
yield index_1.default.remote(opts, caps);
}
catch (e) {
err = e;
}
// we expect an error because appium servers don't allow the authorization header, but if we
// get this far, we knew we sent it ok anyway
err.message.should.match(/Failed to (fetch|create session)/);
});
});
});
describe('Web2Driver - Direct Connect', function () {
let driver = null;
beforeEach(function () {
this.timeout(INIT_TIMEOUT);
});
it('should not use direct connection caps if they are not all present', function () {
return __awaiter(this, void 0, void 0, function* () {
driver = yield index_1.default.remote(OPTS, Object.assign({}, CAPS, {
'appium:directConnectPort': PORT + 1,
}));
yield driver.navigateTo("http://localhost:8080/test/fixture.html");
driver.connectedUrl.should.eql(`http://${SERVER}:${PORT}/`);
});
});
it('should attempt to use new connection details in response capabilities', function () {
return __awaiter(this, void 0, void 0, function* () {
driver = yield index_1.default.remote(OPTS, Object.assign({}, CAPS, {
'appium:directConnectProtocol': 'http',
'appium:directConnectHost': SERVER,
'appium:directConnectPort': PORT,
'appium:directConnectPath': '',
}));
yield driver.navigateTo("http://localhost:8080/test/fixture.html");
driver.connectedUrl.should.eql(`http://${SERVER}:${PORT}`);
});
});
afterEach(function () {
return __awaiter(this, void 0, void 0, function* () {
if (driver) {
yield driver.quit();
driver = null;
}
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90ZXN0L2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7O0FBQUEscURBQWtDO0FBQ2xDLGdEQUF3QjtBQUN4QixvREFBNEI7QUFFNUIsY0FBSSxDQUFDLEdBQUcsQ0FBQyxnQkFBTSxDQUFDLENBQUM7QUFFakIsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDO0FBQzVCLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQztBQUU1QixNQUFNLE1BQU0sR0FBRyxXQUFXLENBQUM7QUFDM0IsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ2xCLE1BQU0sSUFBSSxHQUFHO0lBQ1gsUUFBUSxFQUFFLE1BQU07SUFDaEIsSUFBSSxFQUFFLElBQUk7SUFDVixJQUFJLEVBQUUsR0FBRztJQUNULG9CQUFvQixFQUFFLENBQUM7Q0FDeEIsQ0FBQTtBQUNELE1BQU0sSUFBSSxHQUFHO0lBQ1gsWUFBWSxFQUFFLEtBQUs7SUFDbkIsV0FBVyxFQUFFLFFBQVE7SUFDckIsd0JBQXdCLEVBQUUsTUFBTTtJQUNoQyxtQkFBbUIsRUFBRSxXQUFXO0lBQ2hDLHVCQUF1QixFQUFFLFVBQVU7Q0FDcEMsQ0FBQztBQUVGLE1BQU0sUUFBUSxHQUFHLG9DQUFvQyxDQUFDO0FBRXRELElBQUksT0FBTyxLQUFLLEtBQUssV0FBVyxFQUFFO0lBQ2hDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBQyxPQUFPLEVBQUUsYUFBYSxFQUFDLENBQUMsQ0FBQztDQUN2QztBQUVELFFBQVEsQ0FBQyxZQUFZLEVBQUU7SUFFckIsSUFBSSxNQUFNLENBQUM7SUFFWCxNQUFNLENBQUM7O1lBQ0wsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUUzQixNQUFNLEdBQUcsTUFBTSxlQUFVLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztZQUU3QyxNQUFNLE1BQU0sQ0FB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