UNPKG

@serenity-js/web

Version:

Serenity/JS Screenplay Pattern library offering a flexible, web driver-agnostic approach for interacting with web-based user interfaces and components, suitable for various testing contexts

229 lines 8.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Cookie = void 0; const core_1 = require("@serenity-js/core"); const tiny_types_1 = require("tiny-types"); const errors_1 = require("../../errors"); const abilities_1 = require("../abilities"); /** * A Screenplay Pattern-style model responsible for managing cookies available to the current [`Page`](https://serenity-js.org/api/web/class/Page/). * * ## Checking if a cookie exists * * ```typescript * import { actorCalled } from '@serenity-js/core' * import { Navigate, Cookie } from '@serenity-js/web' * import { Ensure, isPresent } from '@serenity-js/assertions' * * await actorCalled('Sid') * .attemptsTo( * Navigate.to('https://example.org'), * * Ensure.that( * Cookie.called('example-cookie-name'), * isPresent() * ), * ) * ``` * * ## Setting a cookie * * ```typescript * import { actorCalled } from '@serenity-js/core' * import { Navigate, Cookie } from '@serenity-js/web' * import { Ensure, isPresent, not } from '@serenity-js/assertions' * * await actorCalled('Sid') * .attemptsTo( * Navigate.to('https://example.org'), * * Ensure.that(Cookie.called('example-cookie-name'), not(isPresent())), * * Cookie.set({ * name: 'favourite', * value: 'triple chocolate', * }), * * Ensure.that(Cookie.called('example-cookie-name'), isPresent()), * ) * ``` * * ## Reading a cookie * * ```typescript * import { actorCalled } from '@serenity-js/core' * import { Navigate, Cookie } from '@serenity-js/web' * import { Ensure, equals } from '@serenity-js/assertions' * * await actorCalled('Sid') * .attemptsTo( * Navigate.to('https://example.org'), * * Ensure.that( * Cookie.called('some-cookie-name').value(), * equals('triple chocolate') * ), * ) * ``` * * ## Learn more * - [`CookieData`](https://serenity-js.org/api/web/interface/CookieData/) * - [`Page.cookie`](https://serenity-js.org/api/web/class/Page/#cookie) * * @group Models */ class Cookie { cookieName; /** * Creates a [`QuestionAdapter`](https://serenity-js.org/api/core/#QuestionAdapter) that resolves to [`Cookie`](https://serenity-js.org/api/web/class/Cookie/) identified by `name`. * * @param name */ static called(name) { return core_1.Question.about(`"${name}" cookie`, async (actor) => { const cookieName = await actor.answer(name); const page = await abilities_1.BrowseTheWeb.as(actor).currentPage(); return page.cookie(cookieName); }); } /** * Sets a cookie for the current [`Page`](https://serenity-js.org/api/web/class/Page/). Note that [`CookieData`](https://serenity-js.org/api/web/interface/CookieData/) can be either a plain-old JavaScript object, or an [`Answerable`](https://serenity-js.org/api/core/#Answerable) [`WithAnswerableProperties`](https://serenity-js.org/api/core/#WithAnswerableProperties). * * :::info * Make sure that the actor performing this interaction is on the page that should receive the cookie. * Because of browser security restrictions, an actor can't set a cookie for an arbitrary page without being on that page. * ::: * * @param cookieData */ static set(cookieData) { return core_1.Interaction.where((0, core_1.the) `#actor sets cookie: ${cookieData}`, async (actor) => { const cookie = (0, tiny_types_1.ensure)('cookieData', await actor.answer(core_1.Question.fromObject(cookieData)), (0, tiny_types_1.isDefined)(), (0, tiny_types_1.isPlainObject)()); const page = await abilities_1.BrowseTheWeb.as(actor).currentPage(); const sanitisedCookieData = { name: (0, tiny_types_1.ensure)(`Cookie.set(cookieData.name)`, cookie.name, (0, tiny_types_1.isDefined)(), (0, tiny_types_1.isString)()), value: (0, tiny_types_1.ensure)(`Cookie.set(cookieData.value)`, cookie.value, (0, tiny_types_1.isDefined)(), (0, tiny_types_1.isString)()), path: ensureIfPresent(cookie, 'path', (0, tiny_types_1.isString)()), domain: ensureIfPresent(cookie, 'domain', (0, tiny_types_1.isString)()), secure: ensureIfPresent(cookie, 'secure', (0, tiny_types_1.isBoolean)()), httpOnly: ensureIfPresent(cookie, 'httpOnly', (0, tiny_types_1.isBoolean)()), expiry: ensureIfPresent(cookie, 'expiry', (0, tiny_types_1.isInstanceOf)(core_1.Timestamp)), sameSite: ensureIfPresent(cookie, 'sameSite', (0, tiny_types_1.isOneOf)('Lax', 'Strict', 'None')), }; return page.setCookie(sanitisedCookieData); }); } /** * Creates an [interaction](https://serenity-js.org/api/core/class/Interaction/) to delete all cookies available to the current [`Page`](https://serenity-js.org/api/web/class/Page/).. */ static deleteAll() { return core_1.Interaction.where(`#actor deletes all cookies`, async (actor) => { const page = await abilities_1.BrowseTheWeb.as(actor).currentPage(); await page.deleteAllCookies(); }); } cookie; constructor(cookieName) { this.cookieName = cookieName; (0, tiny_types_1.ensure)('browser', cookieName, (0, tiny_types_1.isDefined)()); } /** * Returns the name of this cookie. */ name() { return this.cookieName; } /** * Checks if a given cookie is set. * * #### Learn more * - [`Optional`](https://serenity-js.org/api/core/interface/Optional/) */ async isPresent() { try { const cookie = await this.lazyLoadCookie(); return cookie && cookie.name === this.cookieName; } catch (error) { if (error instanceof errors_1.CookieMissingError) { return false; } throw error; } } /** * Returns the value of a given cookie. */ async value() { const cookie = await this.lazyLoadCookie(); return cookie.value; } /** * Returns the path of a given cookie, if any was set. */ async path() { const cookie = await this.lazyLoadCookie(); return cookie.path; } /** * Returns the domain of a given cookie, if any was set. */ async domain() { const cookie = await this.lazyLoadCookie(); return cookie.domain; } /** * Checks if a given cookie is HTTP-only. * * #### Learn more * - [Mozilla Developer Network: Restricting access to cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) */ async isHttpOnly() { const cookie = await this.lazyLoadCookie(); return cookie.httpOnly; } /** * Checks if a given cookie is secure. * * #### Learn more * - [Mozilla Developer Network: Restricting access to cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) */ async isSecure() { const cookie = await this.lazyLoadCookie(); return cookie.secure; } /** * Returns the expiry date of a given cookie * * #### Learn more * - [`Timestamp`](https://serenity-js.org/api/core/class/Timestamp/) */ async expiry() { const cookie = await this.lazyLoadCookie(); return cookie.expiry; } /** * Invokes `Cookie.read` and caches the result in memory. */ async lazyLoadCookie() { if (!this.cookie) { this.cookie = await this.read(); } return this.cookie; } } exports.Cookie = Cookie; /** * @ignore * @private * * @param data * @param property * @param predicates */ function ensureIfPresent(data, property, ...predicates) { return data[property] ? (0, tiny_types_1.ensure)(`Cookie.set(cookieData.${property})`, data[property], ...predicates) : undefined; } //# sourceMappingURL=Cookie.js.map