UNPKG

qe-fe-automation

Version:
231 lines (216 loc) 8.66 kB
import dayjs from 'dayjs'; import { createGuestDetails } from '@support-user/index'; import { UserModal } from '../lib/user-modal'; import { Timeouts, TripTileType, utilitySelector } from '@utility-lib/index'; const selectors = { givenNameInput: 'input[formcontrolname="givenName"]', familyNameInput: 'input[formcontrolname="familyName"]', genderInput: 'ta-select[formcontrolname="gender"] .ta-select', birthdayInput: 'input[placeholder="MM/DD/YYYY"]', birthdayField: 'ta-date-input[formcontrolname="birthdate"] input', phoneInput: 'ta-phone-input[formcontrolname="mobilePhone"]', phoneValue: 'input.ta-phone-input__template', saveFooterButton: '[data-testid="stickyPrimaryButton"]', passportIssuingInput: 'ta-country-select[formcontrolname="countryOfIssue"]', passportCitizenshipInput: 'ta-country-select[formcontrolname="countryOfCitizenship"]', passportDateIssued: 'ta-date-input[formcontrolname="issuedOn"]', passportDateExpired: 'ta-date-input[formcontrolname="expiresOn"]', passportNumber: 'input[formcontrolname="number"]' }; interface Passport { country: string; issue: string; expire: string; number: string; } export class TravelerModal { static interceptApis(numRetries: number, aliasName: string): void { if (numRetries === 0) { throw new Error(`Could not find property '${'givenName'}' after multiple attempts`); } cy.intercept('GET', '/api/user/passenger').as(aliasName); cy.allure().logStep('Visit profile page on traveler tab'); this.visitPage(); cy.wait(`@${aliasName}`).then((interception) => { const response = interception.response; if (response && Object.prototype.hasOwnProperty.call(response.body, 'givenName')) { // Response has the expected property, proceed with the test cy.wrap(response.body['givenName']).as('givenName'); } else { // Response is missing the expected property, retry after 1 second with a new intercept cy.log('Bad API response, retrying...'); cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout); TravelerModal.interceptApis(numRetries - 1, aliasName); } }); } static visitPage(): void { cy.allure().logStep('Visit profile page on traveler tab'); cy.visit('app/user2/profile?tab=traveler'); } static getTravelerInfo(): void { cy.wait('@travelerInfo').then((interception) => { // Gets traveler's current information and saves them as aliases const response = interception.response; if (response) { const properties = ['givenName', 'familyName', 'gender', 'birthdate']; properties.forEach((property) => { cy.wrap(response.body) .should('have.property', property) .as(`org${property.charAt(0).toUpperCase()}${property.slice(1)}`); }); cy.wrap(response.body) .should('have.nested.property', 'contact.phone.number') .as('orgPhoneNumber'); } }); } static compareTravelerInfo(): void { cy.reload(); const aliasName = 'newTravelerInfo'; TravelerModal.interceptApis(3, aliasName); cy.wait(`@${aliasName}`).then((interception) => { // Gets traveler's new information and saves them as new aliases const response = interception.response; function setAliasForProperty(propertyName: string) { cy.wrap(response?.body) .should('have.property', propertyName) .as(`new${propertyName.charAt(0).toUpperCase()}${propertyName.slice(1)}`); } if (response) { setAliasForProperty('givenName'); setAliasForProperty('familyName'); setAliasForProperty('gender'); setAliasForProperty('birthdate'); cy.wrap(response.body) .should('have.nested.property', 'contact.phone.number') .as('newPhoneNumber'); } }); // Confirms on the API level that the traveler's info has been updated const properties = { orgGivenName: 'newGivenName', orgFamilyName: 'newFamilyName', orgGender: 'newGender', orgBirthdate: 'newBirthdate', orgPhoneNumber: 'newPhoneNumber' }; // Confirms that the UI is also displaying the updated traveler's info this.compareUIProperties(selectors.givenNameInput, properties.orgGivenName); this.compareUIProperties(selectors.familyNameInput, properties.orgFamilyName); // Phone, Birthday and Gender require unique comparisons cy.get(selectors.phoneValue) .invoke('val') .then((displayedPhoneNumber) => { const phoneStr = displayedPhoneNumber?.toString().replace(/[\s⚊]+/g, ''); cy.get('@newPhoneNumber').then((value) => { expect(phoneStr).to.equal(value); }); }); cy.get(selectors.birthdayInput) .invoke('val') .then((displayedBirthday) => { const dateStr = displayedBirthday?.toString(); const formattedDate = dayjs(dateStr).format('YYYY-MM-DD'); cy.get('@newBirthdate').then((value) => { expect(formattedDate).to.equal(value); }); }); cy.get('@newGender').then((value1) => { cy.get(selectors.genderInput) .invoke('attr', 'value') .then((value2) => { if (value2) { const uppercaseValue2 = value2.toUpperCase().trim(); expect(value1).to.equal(uppercaseValue2); } }); }); } static compareAPIProperties(oldAlias: string, newAlias: string) { cy.get('@' + oldAlias).then((value1) => { cy.get('@' + newAlias).then((value2) => { expect(value1).to.not.equal(value2); }); }); } static compareUIProperties(selector: string, newAlias: string) { cy.get(selector) .invoke('val') .then((value1) => { cy.get('@' + newAlias).then((value2) => { expect(value1).to.equal(value2); }); }); } static createNewTravelerInfo( travelerType: TripTileType, gender: 'MALE' | 'FEMALE', age: number ) { const { givenName = '', familyName = '', phoneNumber = '' } = createGuestDetails(age, gender, travelerType); // The /api/user/passenger API only stores the first 11 numbers of a phone number, so we'll trim the phone number here down to 11 characters (with a '+') const maxLength = 12; cy.wrap(phoneNumber) .invoke('substring', 0, maxLength) .then((number) => { const trimNumber = number; // Adds and saves new traveler information cy.get(selectors.birthdayField).clear(); UserModal.fillTravelerName(givenName, familyName); UserModal.fillBirthday(age); UserModal.fillGender(gender); UserModal.fillPhoneNumber(trimNumber); cy.get(selectors.saveFooterButton).click(); }); } static updatePassportInfo(passport: Passport) { const { country, issue, expire, number } = passport; // Enters generated passport information into the passport fields cy.get(selectors.passportIssuingInput).type( '{selectall}{backspace}' + country + '{enter}' ); cy.get(selectors.passportCitizenshipInput).type( '{selectall}{backspace}' + country + '{enter}' ); cy.get(selectors.passportDateIssued).type('{selectall}{backspace}' + issue); cy.get(selectors.passportDateExpired).type('{selectall}{backspace}' + expire); cy.get(selectors.passportNumber).type('{selectall}{backspace}' + number); cy.get(selectors.saveFooterButton).click(); } static verifyUpdatedPassportInfo(passport: Passport) { const { country, issue, expire, number } = passport; cy.reload(); cy.get(selectors.passportIssuingInput) .find(utilitySelector.inputSelector) .should('have.value', country); cy.get(selectors.passportCitizenshipInput) .find(utilitySelector.inputSelector) .should('have.value', country); cy.get(selectors.passportDateIssued) .find(utilitySelector.inputSelector) .invoke('val') .then((value1) => { const dateStr = value1?.toString(); const passportFormattedIssueDate = dayjs(dateStr, 'MMM D, YYYY').format( 'MMDDYYYY' ); expect(passportFormattedIssueDate).to.equal(issue); }); cy.get(selectors.passportDateExpired) .find(utilitySelector.inputSelector) .invoke('val') .then((value) => { const dateStr = value?.toString(); const passportFormattedExpiredDate = dayjs(dateStr, 'MMM D, YYYY').format( 'MMDDYYYY' ); expect(passportFormattedExpiredDate).to.equal(expire); }); cy.get(selectors.passportNumber).should('have.value', number); } }