@serenity-js/protractor
Version:
Adapter that integrates @serenity-js/web with Protractor, enabling Serenity/JS reporting and using the Screenplay Pattern to write end-to-end test scenarios
107 lines • 5.22 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProtractorBrowsingSession = void 0;
const model_1 = require("@serenity-js/core/lib/model");
const web_1 = require("@serenity-js/web");
const models_1 = require("../models");
const promised_1 = require("../promised");
const ProtractorErrorHandler_1 = require("./ProtractorErrorHandler");
const ProtractorModalDialogHandler_1 = require("./ProtractorModalDialogHandler");
/**
* Protractor-specific implementation of [`BrowsingSession`](https://serenity-js.org/api/web/class/BrowsingSession/).
*
* @group Models
*/
class ProtractorBrowsingSession extends web_1.BrowsingSession {
browser;
constructor(browser) {
super();
this.browser = browser;
}
async allPages() {
// scan all the active window handles and add any newly opened windows if needed
const windowHandles = await (0, promised_1.promised)(this.browser.getAllWindowHandles());
// remove pages that are no longer open
const closedPageIds = this.registeredPageIds()
.filter(id => !windowHandles.includes(id.value));
this.deregister(...closedPageIds);
// add any new pages that might have been opened (e.g. popup windows)
const registeredWindowHandles = new Set(this.registeredPageIds().map(id => id.value));
const newlyOpenedWindowHandles = windowHandles.filter(windowHandle => !registeredWindowHandles.has(windowHandle));
for (const newlyOpenedWindowHandle of newlyOpenedWindowHandles) {
const errorHandler = new ProtractorErrorHandler_1.ProtractorErrorHandler();
this.register(new models_1.ProtractorPage(this, this.browser, new ProtractorModalDialogHandler_1.ProtractorModalDialogHandler(this.browser, errorHandler), errorHandler, new model_1.CorrelationId(newlyOpenedWindowHandle)));
}
return super.allPages();
}
/**
* @param page
*/
async changeCurrentPageTo(page) {
const currentPage = await this.currentPage();
// are we already on this page?
if (currentPage.id.equals(page.id)) {
return void 0;
}
// does the new page exist, or has it been closed in the meantime by user action, script, or similar?
if (!await page.isPresent()) {
return void 0;
}
// the page seems to be legit, switch to it
await (0, promised_1.promised)(this.browser.switchTo().window(page.id.value));
// and update the cached reference
await super.changeCurrentPageTo(page);
}
async activeWindowHandle() {
try {
return await (0, promised_1.promised)(this.browser.getWindowHandle());
}
catch (error) {
// If the window is closed by user action Protractor will still hold the reference to the closed window.
if (['NoSuchWindowError', 'no such window'].includes(error.name)) {
const allHandles = await (0, promised_1.promised)(this.browser.getAllWindowHandles());
if (allHandles.length > 0) {
const handle = allHandles.at(-1);
await (0, promised_1.promised)(this.browser.switchTo().window(handle));
return handle;
}
}
throw error;
}
}
async currentPage() {
const actualCurrentPageHandle = await this.activeWindowHandle();
const actualCurrentPageId = model_1.CorrelationId.fromJSON(actualCurrentPageHandle);
if (this.currentBrowserPage && this.currentBrowserPage.id.equals(actualCurrentPageId)) {
return this.currentBrowserPage;
}
// Looks like the actual current page is not what we thought the current page was.
// Is it one of the pages we are aware of?
const allPages = await this.allPages();
const found = allPages.find(page => page.id.equals(actualCurrentPageId));
if (found) {
this.currentBrowserPage = found;
return this.currentBrowserPage;
}
// OK, so that's a handle that we haven't seen before, let's register it and set as current page.
this.currentBrowserPage = await this.registerCurrentPage();
return this.currentBrowserPage;
}
async registerCurrentPage() {
const windowHandle = await this.browser.getWindowHandle();
const errorHandler = new ProtractorErrorHandler_1.ProtractorErrorHandler();
const page = new models_1.ProtractorPage(this, this.browser, new ProtractorModalDialogHandler_1.ProtractorModalDialogHandler(this.browser, errorHandler), errorHandler, new model_1.CorrelationId(windowHandle));
this.register(page);
return page;
}
async browserCapabilities() {
const capabilities = await (0, promised_1.promised)(this.browser.getCapabilities());
return {
platformName: capabilities.get('platform'),
browserName: capabilities.get('browserName'),
browserVersion: capabilities.get('version'),
};
}
}
exports.ProtractorBrowsingSession = ProtractorBrowsingSession;
//# sourceMappingURL=ProtractorBrowsingSession.js.map