mirror of
https://gh.wpcy.net/https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2026-04-25 01:02:18 +08:00
362 lines
11 KiB
TypeScript
362 lines
11 KiB
TypeScript
/**
|
|
* Internal dependencies
|
|
*/
|
|
import { expect } from '../test';
|
|
import { PcpAdminPage } from './pcp-admin-page';
|
|
import urls from '../urls';
|
|
import { Pcp } from '../../resources';
|
|
|
|
export class PcpPayLaterMessaging extends PcpAdminPage {
|
|
url = urls.admin.pcp.payLaterMessaging;
|
|
|
|
// Locators
|
|
configContainer = () => this.page.locator( '#messaging-configurator' );
|
|
accordionButton = ( location: Pcp.Admin.Plm.Location ) =>
|
|
this.page.getByRole( 'button', { name: location } );
|
|
accordionButtonSvgPath = ( location: Pcp.Admin.Plm.Location ) =>
|
|
this.accordionButton( location ).locator( 'svg path' );
|
|
accordionContainer = ( location: Pcp.Admin.Plm.Location ) =>
|
|
this.page
|
|
.locator( 'div[accordionname="message-configs"]' )
|
|
.filter( { has: this.accordionButton( location ) } );
|
|
accordionCheckbox = ( location: Pcp.Admin.Plm.Location ) =>
|
|
this.accordionContainer( location ).locator(
|
|
'div[data-id="checkbox"] label[for^="Checkbox"]'
|
|
);
|
|
accordionCheckboxSvg = ( location: Pcp.Admin.Plm.Location ) =>
|
|
this.accordionCheckbox( location ).locator( 'svg' );
|
|
|
|
logoTypeCombobox = ( location: Pcp.Admin.Plm.Location ) =>
|
|
this.accordionContainer( location ).locator(
|
|
'button[aria-labelledby^="dropdownMenuButton_Logotype"]'
|
|
);
|
|
textColorCombobox = ( location: Pcp.Admin.Plm.Location ) =>
|
|
this.accordionContainer( location ).locator(
|
|
'button[aria-labelledby^="dropdownMenuButton_Textcolor"]'
|
|
);
|
|
logoPositionCombobox = ( location: Pcp.Admin.Plm.Location ) =>
|
|
this.accordionContainer( location ).locator(
|
|
'button[aria-labelledby^="dropdownMenuButton_Logoposition"]'
|
|
);
|
|
textSizeCombobox = ( location: Pcp.Admin.Plm.Location ) =>
|
|
this.accordionContainer( location ).locator(
|
|
'button[aria-labelledby^="dropdownMenuButton_Textsize"]'
|
|
);
|
|
bannerColorCombobox = ( location: Pcp.Admin.Plm.Location ) =>
|
|
this.accordionContainer( location ).locator(
|
|
'button[aria-labelledby^="dropdownMenuButton_Bannercolor"]'
|
|
);
|
|
bannerSizeCombobox = ( location: Pcp.Admin.Plm.Location ) =>
|
|
this.accordionContainer( location ).locator(
|
|
'button[aria-labelledby^="dropdownMenuButton_Bannersize"]'
|
|
);
|
|
comboboxOption = ( optionName: string ) => {
|
|
const escaped = optionName.replace(
|
|
/[.*+?^${}()|[\]\\]/g,
|
|
'\\$&'
|
|
);
|
|
return this.page
|
|
.locator( 'li[id^="smenu_item_"]' )
|
|
.filter( {
|
|
hasText: new RegExp( `^${ escaped }$`, 'i' ),
|
|
} )
|
|
.first();
|
|
};
|
|
previewContainer = () =>
|
|
this.page.locator( '#configurator-previewSectionContainer' );
|
|
previewIframe = () =>
|
|
this.previewContainer().locator( 'iframe' ).first();
|
|
previewTextButton = () =>
|
|
this.page.locator(
|
|
'svg path[d="M5 5a1 1 0 0 0 0 2h14a1 1 0 1 0 0-2H5zm-1 7a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1zm0 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1z"]'
|
|
);
|
|
previewDesktopButton = () =>
|
|
this.page.locator(
|
|
'svg path[d="M4 5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v11a1 1 0 0 1-1 1h-6v2h2.25a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5H11v-2H5a1 1 0 0 1-1-1V5zm2 9.25a.75.75 0 0 1 .75-.75h10.5a.75.75 0 0 1 0 1.5H6.75a.75.75 0 0 1-.75-.75z"]'
|
|
);
|
|
previewMobileButton = () =>
|
|
this.page.locator(
|
|
'svg path[d="M6 2a1 1 0 0 0-1 1v18a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H6zm6 18a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"]'
|
|
);
|
|
darkModeToggle = () =>
|
|
this.page.locator(
|
|
'label[for="configurator-previewSectionDarkModeToggle"]'
|
|
);
|
|
|
|
// Actions
|
|
|
|
/**
|
|
* Expands section of the accordion by provided location.
|
|
* Simply clicking on a button doesn't work because there's no way to tell if section is expanded.
|
|
* Unfortunately there's no other way to differentiate between collapsed and expanded section except svg path value.
|
|
*
|
|
* @param {Pcp.Admin.Plm.Location} location
|
|
*/
|
|
expandAccordionSection = async ( location: Pcp.Admin.Plm.Location ) => {
|
|
// Get the current path data
|
|
const pathData = await this.accordionButtonSvgPath(
|
|
location
|
|
).getAttribute( 'd' );
|
|
|
|
// Expected values (replace with correct ones if needed)
|
|
const collapsedPath =
|
|
'M4.292 8.293a1 1 0 0 1 1.414 0L12 14.586l6.293-6.293a1 1 0 0 1 1.414 1.414L12.713 16.7a1.01 1.01 0 0 1-1.428 0L4.292 9.707a1 1 0 0 1 0-1.414z';
|
|
const expandedPath =
|
|
'M4.293 15.703a1 1 0 0 0 1.414 0L12 9.41l6.293 6.293a1 1 0 0 0 1.414-1.414l-6.993-6.993a1.01 1.01 0 0 0-1.428 0l-6.993 6.993a1 1 0 0 0 0 1.414z';
|
|
|
|
if ( pathData === collapsedPath ) {
|
|
await this.accordionButton( location ).click();
|
|
await expect(
|
|
this.accordionButtonSvgPath( location ),
|
|
`Assert accordion section ${ location } is expanded`
|
|
).toHaveAttribute( 'd', expandedPath );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Checks if messaging for location is enabled.
|
|
*
|
|
* @param location
|
|
*/
|
|
isMessagingForLocationEnabled = async (
|
|
location: Pcp.Admin.Plm.Location
|
|
) => {
|
|
// Get the current 'color' property of SVG
|
|
const color = await this.accordionCheckboxSvg( location ).evaluate(
|
|
( el ) => getComputedStyle( el ).color
|
|
);
|
|
// Expected colors
|
|
const checkedColor = 'rgb(255, 255, 255)'; // White (checked)
|
|
const isEnabled = color === checkedColor;
|
|
return isEnabled;
|
|
};
|
|
|
|
/**
|
|
* Enables/disabled messaging for location.
|
|
* Waits for checkbox state to change after click (no hard timeouts).
|
|
*
|
|
* @param location
|
|
* @param isChecked
|
|
*/
|
|
setMessagingCheckboxStateForLocation = async (
|
|
location: Pcp.Admin.Plm.Location,
|
|
isChecked: boolean
|
|
) => {
|
|
const isEnabled = await this.isMessagingForLocationEnabled( location );
|
|
if ( isEnabled !== isChecked ) {
|
|
await this.accordionCheckbox( location ).click();
|
|
await expect
|
|
.poll(
|
|
() => this.isMessagingForLocationEnabled( location ),
|
|
`Assert ${ location } checkbox is ${ isChecked ? 'enabled' : 'disabled' }`
|
|
)
|
|
.toBe( isChecked );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Enables messaging for location.
|
|
*
|
|
* @param location
|
|
*/
|
|
enableMessagingForLocation = async ( location: Pcp.Admin.Plm.Location ) =>
|
|
this.setMessagingCheckboxStateForLocation( location, true );
|
|
|
|
/**
|
|
* Disables messaging for location.
|
|
*
|
|
* @param location
|
|
*/
|
|
disableMessagingForLocation = async ( location: Pcp.Admin.Plm.Location ) =>
|
|
this.setMessagingCheckboxStateForLocation( location, false );
|
|
|
|
/**
|
|
* Enables messaging for WooCommerce Block placement (custom_placement).
|
|
* Required for the PLM block to render on custom pages.
|
|
*/
|
|
enableMessagingForWooCommerceBlock = async () =>
|
|
this.enableMessagingForLocation( 'WooCommerce Block' );
|
|
|
|
/**
|
|
* Toggles dark mode on/off.
|
|
*
|
|
* @param isEnabled
|
|
*/
|
|
setDarkModeToggleState = async ( isEnabled: boolean ) => {
|
|
const toggle = this.darkModeToggle();
|
|
// Get the current 'color' property
|
|
const color = await toggle.evaluate(
|
|
( el ) => getComputedStyle( el ).borderBottomColor
|
|
);
|
|
// Expected colors
|
|
const uncheckedColor = 'rgb(146, 148, 150)'; // White (unchecked)
|
|
const isChecked = color !== uncheckedColor;
|
|
if ( isChecked !== isEnabled ) {
|
|
await toggle.click();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Toggles dark mode on.
|
|
*/
|
|
enableDarkModeToggle = async () => this.setDarkModeToggleState( true );
|
|
|
|
/**
|
|
* Toggles dark mode off.
|
|
*/
|
|
disableDarkModeToggle = async () => this.setDarkModeToggleState( false );
|
|
|
|
/**
|
|
* Sets combobox settings for location
|
|
*
|
|
* @param location
|
|
* @param settings
|
|
* @param settings.logoType
|
|
* @param settings.textColor
|
|
* @param settings.logoPosition
|
|
* @param settings.textSize
|
|
* @param settings.bannerColor
|
|
* @param settings.bannerSize
|
|
*/
|
|
updateLocationSettings = async (
|
|
location: Pcp.Admin.Plm.Location,
|
|
settings: {
|
|
logoType?: Pcp.Admin.Plm.LogoType;
|
|
textColor?: Pcp.Admin.Plm.TextColor;
|
|
logoPosition?: Pcp.Admin.Plm.LogoPosition;
|
|
textSize?: Pcp.Admin.Plm.TextSize;
|
|
bannerColor?: Pcp.Admin.Plm.BannerColor;
|
|
bannerSize?: Pcp.Admin.Plm.BannerSize;
|
|
}
|
|
) => {
|
|
const {
|
|
logoType,
|
|
textColor,
|
|
logoPosition,
|
|
textSize,
|
|
bannerColor,
|
|
bannerSize,
|
|
} = settings;
|
|
|
|
await this.expandAccordionSection( location );
|
|
|
|
if ( logoType ) {
|
|
await this.logoTypeCombobox( location ).click();
|
|
await this.comboboxOption( logoType ).click();
|
|
}
|
|
|
|
if ( textColor ) {
|
|
await this.textColorCombobox( location ).click();
|
|
await this.comboboxOption( textColor ).click();
|
|
}
|
|
|
|
if ( logoPosition && logoType === 'Full logo' ) {
|
|
await this.logoPositionCombobox( location ).click();
|
|
await this.comboboxOption( logoPosition ).click();
|
|
}
|
|
|
|
if ( textSize ) {
|
|
await this.textSizeCombobox( location ).click();
|
|
await this.comboboxOption( textSize ).click();
|
|
}
|
|
|
|
if ( bannerColor ) {
|
|
await this.bannerColorCombobox( location ).click();
|
|
await this.comboboxOption( bannerColor ).click();
|
|
}
|
|
|
|
if ( bannerSize ) {
|
|
await this.bannerSizeCombobox( location ).click();
|
|
await this.comboboxOption( bannerSize ).click();
|
|
}
|
|
};
|
|
|
|
// Assertions
|
|
|
|
/**
|
|
* Softly asserts combobox settings for location
|
|
*
|
|
* @param settings
|
|
* @param settings.logoType
|
|
* @param settings.textColor
|
|
* @param settings.logoPosition
|
|
* @param settings.textSize
|
|
* @param settings.bannerColor
|
|
* @param settings.bannerSize
|
|
*/
|
|
assertLocationSettings = async (
|
|
location: Pcp.Admin.Plm.Location,
|
|
settings: {
|
|
logoType?: Pcp.Admin.Plm.LogoType;
|
|
textColor?: Pcp.Admin.Plm.TextColor;
|
|
logoPosition?: Pcp.Admin.Plm.LogoPosition;
|
|
textSize?: Pcp.Admin.Plm.TextSize;
|
|
bannerColor?: Pcp.Admin.Plm.BannerColor;
|
|
bannerSize?: Pcp.Admin.Plm.BannerSize;
|
|
}
|
|
) => {
|
|
const {
|
|
logoType,
|
|
textColor,
|
|
logoPosition,
|
|
textSize,
|
|
bannerColor,
|
|
bannerSize,
|
|
} = settings;
|
|
|
|
if ( logoType ) {
|
|
await expect(
|
|
this.logoTypeCombobox( location ),
|
|
`Assert logo type is ${ logoType }`
|
|
).toHaveText( logoType );
|
|
}
|
|
|
|
if ( textColor ) {
|
|
await expect(
|
|
this.textColorCombobox( location ),
|
|
`Assert text color is ${ textColor }`
|
|
).toHaveText( textColor );
|
|
}
|
|
|
|
if ( logoPosition && logoType === 'Full logo' ) {
|
|
await expect(
|
|
this.logoPositionCombobox( location ),
|
|
`Assert logo position is ${ logoPosition }`
|
|
).toHaveText( logoPosition );
|
|
}
|
|
|
|
if ( textSize ) {
|
|
await expect(
|
|
this.textSizeCombobox( location ),
|
|
`Assert text size is ${ textSize }`
|
|
).toHaveText( textSize );
|
|
}
|
|
|
|
if ( bannerColor ) {
|
|
await expect(
|
|
this.bannerColorCombobox( location ),
|
|
`Assert banner color is ${ bannerColor }`
|
|
).toHaveText( bannerColor );
|
|
}
|
|
|
|
if ( bannerSize ) {
|
|
await expect(
|
|
this.bannerSizeCombobox( location ),
|
|
`Assert banner size is ${ bannerSize }`
|
|
).toHaveText( bannerSize );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Asserts the PLM configurator preview shows the message (element-based).
|
|
* For banner layouts (Home/Shop), the message text may be hidden initially;
|
|
* we assert the preview iframe is present instead.
|
|
*/
|
|
assertPreviewShowsMessage = async () => {
|
|
// Assert preview iframe is visible (works for all layouts including banner)
|
|
await expect(
|
|
this.previewIframe(),
|
|
'Assert PLM preview iframe is visible'
|
|
).toBeVisible();
|
|
};
|
|
}
|