Skip to content

Commit

Permalink
fix: jwpltx crash fix and multiple test improvements
Browse files Browse the repository at this point in the history
* fix: null ref in jwpltx crashing e2e tests

* chore(project): test fixes

* chore: fix payments tests

* chore: fix scrolling and finding tests

* chore: fix more tests

---------

Co-authored-by: Danny Budzinski <dbudzinski@jwplayer.com>
  • Loading branch information
AntonLantukh and dbudzins authored Sep 25, 2023
1 parent be3c907 commit 4118327
Show file tree
Hide file tree
Showing 17 changed files with 558 additions and 455 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
"lint:ts": "tsc --pretty --noEmit -p .",
"lint:stylelint": "stylelint '**/*.{css,scss}'",
"commit-msg": "commitlint --edit $1",
"codecept:mobile": "cd test-e2e && rm -rf \"./output/mobile\" && codeceptjs --config ./codecept.mobile.js run-workers --suites ${WORKER_COUNT:=8} ",
"codecept:desktop": "cd test-e2e && rm -rf \"./output/desktop\" && codeceptjs --config ./codecept.desktop.js run-workers --suites ${WORKER_COUNT:=8} ",
"codecept:mobile": "cd test-e2e && rm -rf \"./output/mobile\" && codeceptjs run-workers --suites ${WORKER_COUNT:=8} --config ./codecept.mobile.js",
"codecept:desktop": "cd test-e2e && rm -rf \"./output/desktop\" && codeceptjs run-workers --suites ${WORKER_COUNT:=8} --config ./codecept.desktop.js",
"serve-report:mobile": "cd test-e2e && allure serve \"./output/mobile\"",
"serve-report:desktop": "cd test-e2e && allure serve \"./output/desktop\"",
"codecept-serve:mobile": "yarn codecept:mobile ; yarn serve-report:mobile",
Expand Down Expand Up @@ -90,7 +90,7 @@
"@vitejs/plugin-react": "^4.0.4",
"@vitest/coverage-v8": "^0.33.0",
"allure-commandline": "^2.17.2",
"codeceptjs": "3.4.1",
"codeceptjs": "3.5.5",
"confusing-browser-globals": "^1.0.10",
"csv-parse": "^5.4.0",
"depcheck": "^1.4.3",
Expand All @@ -106,7 +106,7 @@
"lint-staged": "^10.5.4",
"luxon": "^3.2.1",
"npm-run-all": "^4.1.5",
"playwright": "^1.33.0",
"playwright": "^1.38.1",
"postcss": "^8.3.5",
"postcss-import": "^14.0.2",
"postcss-scss": "^4.0.4",
Expand Down
9 changes: 7 additions & 2 deletions public/jwpltx.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,16 @@ window.jwpltx = window.jwpltx || {};

// Sends the last ping when closing the player or window
function sendRemainingData() {
// This is rare, but happens in e2e tests and can occur if the user closes the player really fast before any ticks.
// There is no data, so just skip.
if (!uri) {
return;
}

if (uri.pw === -1) {
clearLiveInterval();
} else {
const pw = getCurrentProgressQuantile(lastVp, uri.vd);
uri.pw = pw;
uri.pw = getCurrentProgressQuantile(lastVp, uri.vd);
}

clearSeekingTimeout();
Expand Down
12 changes: 11 additions & 1 deletion src/components/DevConfigSelector/DevConfigSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,17 @@ const DevConfigSelector = ({ selectedConfig }: Props) => {
[configNavigate],
);

return <Dropdown className={styles.dropdown} size="small" options={configOptions} name="config-select" value={selectedConfig || ''} onChange={onChange} />;
return (
<Dropdown
className={styles.dropdown}
size="small"
options={configOptions}
name="config-select"
value={selectedConfig || ''}
onChange={onChange}
required={true}
/>
);
};

export default DevConfigSelector;
4 changes: 4 additions & 0 deletions src/containers/Layout/Layout.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ div.footer {
}
}

div.testFixMargin {
margin-bottom: 50px;
}

.divider {
width: 100%;
border: none;
Expand Down
11 changes: 10 additions & 1 deletion src/containers/Layout/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Helmet } from 'react-helmet';
import { useTranslation } from 'react-i18next';
import { Outlet, useLocation, useNavigate } from 'react-router';
import shallow from 'zustand/shallow';
import classNames from 'classnames';

import styles from './Layout.module.scss';

Expand All @@ -21,6 +22,7 @@ import { addQueryParam } from '#src/utils/location';
import { getSupportedLanguages } from '#src/i18n/config';
import { useProfileStore } from '#src/stores/ProfileStore';
import { unpersistProfile, useProfiles } from '#src/hooks/useProfiles';
import { IS_DEVELOPMENT_BUILD } from '#src/utils/common';

const Layout = () => {
const location = useLocation();
Expand Down Expand Up @@ -169,7 +171,14 @@ const Layout = () => {
</Sidebar>
<Outlet />
</div>
{!!footerText && <MarkdownComponent className={styles.footer} markdownString={footerText} inline />}
{!!footerText && (
<MarkdownComponent
// The extra style below is just to fix the footer on mobile when the dev selector is shown
className={classNames(styles.footer, { [styles.testFixMargin]: IS_DEVELOPMENT_BUILD })}
markdownString={footerText}
inline
/>
)}
</div>
);
};
Expand Down
4 changes: 2 additions & 2 deletions test-e2e/codecept.desktop.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ exports.config = {
grep: '(?=.*)^(?!.*@mobile-only)',
tests: ['./tests/**/*.js', './tests/**/*.ts'],
output: './output/desktop',
timeout: 3000,
timeout: 60,
helpers: {
Playwright: {
url: 'http://localhost:8080',
Expand All @@ -30,7 +30,7 @@ exports.config = {
plugins: {
pauseOnFail: {},
retryFailedStep: {
minTimeout: 100,
minTimeout: 1000,
enabled: true,
retries: 5,
},
Expand Down
4 changes: 2 additions & 2 deletions test-e2e/codecept.mobile.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ exports.config = {
grep: '(?=.*)^(?!.*@desktop-only)',
tests: ['./tests/**/*.js', './tests/**/*.ts'],
output: './output/mobile',
timeout: 3000,
timeout: 60,
helpers: {
Playwright: {
url: 'http://localhost:8080',
Expand All @@ -31,7 +31,7 @@ exports.config = {
plugins: {
pauseOnFail: {},
retryFailedStep: {
minTimeout: 100,
minTimeout: 1000,
enabled: true,
retries: 5,
},
Expand Down
33 changes: 19 additions & 14 deletions test-e2e/tests/account_test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import passwordUtils, { LoginContext } from '#utils/password_utils';
import constants from '#utils/constants';
import constants, { longTimeout, normalTimeout } from '#utils/constants';
import { testConfigs } from '#test/constants';

const editAccount = 'Edit account';
const editDetials = 'Edit information';
const editDetails = 'Edit information';
const emailField = 'email';
const passwordField = 'confirmationPassword';
const firstNameField = 'firstName';
Expand Down Expand Up @@ -149,21 +149,21 @@ function runTestSuite(config: typeof testConfigs.svod, providerName: string, res
});

Scenario(`I can update firstName - ${providerName}`, async ({ I }) => {
editAndSave(I, editDetials, [
editAndSave(I, editDetails, [
{
name: firstNameField,
newValue: '',
},
]);

editAndSave(I, editDetials, [
editAndSave(I, editDetails, [
{
name: firstNameField,
newValue: 'Jack',
},
]);

editAndSave(I, editDetials, [
editAndSave(I, editDetails, [
{
name: firstNameField,
newValue: firstName,
Expand All @@ -172,21 +172,21 @@ function runTestSuite(config: typeof testConfigs.svod, providerName: string, res
});

Scenario(`I can update lastName - ${providerName}`, async ({ I }) => {
editAndSave(I, editDetials, [
editAndSave(I, editDetails, [
{
name: lastNameField,
newValue: '',
},
]);

editAndSave(I, editDetials, [
editAndSave(I, editDetails, [
{
name: lastNameField,
newValue: 'Jones',
},
]);

editAndSave(I, editDetials, [
editAndSave(I, editDetails, [
{
name: lastNameField,
newValue: lastName,
Expand All @@ -195,7 +195,7 @@ function runTestSuite(config: typeof testConfigs.svod, providerName: string, res
});

Scenario(`I can update details - ${providerName}`, async ({ I }) => {
editAndSave(I, editDetials, [
editAndSave(I, editDetails, [
{
name: firstNameField,
newValue: '',
Expand All @@ -206,7 +206,7 @@ function runTestSuite(config: typeof testConfigs.svod, providerName: string, res
},
]);

editAndSave(I, editDetials, [
editAndSave(I, editDetails, [
{
name: firstNameField,
newValue: 'Newname',
Expand All @@ -217,7 +217,7 @@ function runTestSuite(config: typeof testConfigs.svod, providerName: string, res
},
]);

editAndSave(I, editDetials, [
editAndSave(I, editDetails, [
{
name: firstNameField,
newValue: firstName,
Expand All @@ -230,7 +230,7 @@ function runTestSuite(config: typeof testConfigs.svod, providerName: string, res
});

Scenario(`I see name limit errors - ${providerName}`, async ({ I }) => {
editAndCancel(I, editDetials, [
editAndCancel(I, editDetails, [
{
name: firstNameField,
startingValue: firstName,
Expand All @@ -248,6 +248,8 @@ function runTestSuite(config: typeof testConfigs.svod, providerName: string, res

Scenario(`I can update my consents - ${providerName}`, async ({ I }) => {
I.amOnPage(constants.accountsUrl);
I.waitForText('Profile info', longTimeout);
I.scrollTo('//*[text() = "Other registration details"]');

I.dontSeeCheckboxIsChecked(consentCheckbox);
I.dontSee('Save');
Expand All @@ -259,6 +261,7 @@ function runTestSuite(config: typeof testConfigs.svod, providerName: string, res
I.see('Save');
I.see('Cancel');

I.scrollTo('//*[text() = "Cancel"]');
I.click('Cancel');

I.dontSeeCheckboxIsChecked(consentCheckbox);
Expand All @@ -270,6 +273,7 @@ function runTestSuite(config: typeof testConfigs.svod, providerName: string, res
I.see('Save');
I.see('Cancel');

I.scrollTo('//*[text() = "Save"]');
I.click('Save');
I.waitForLoaderDone();

Expand Down Expand Up @@ -298,7 +302,8 @@ function runTestSuite(config: typeof testConfigs.svod, providerName: string, res

function editAndSave(I: CodeceptJS.I, editButton: string, fields: { name: string; newValue: string; expectedError?: string }[]) {
I.amOnPage(constants.accountsUrl);

I.waitForElement(`//*[text() = "${editButton}"]`, normalTimeout);
I.scrollTo(`//*[text() = "${editButton}"]`);
I.click(editButton);

I.see('Save');
Expand Down Expand Up @@ -356,7 +361,7 @@ function runTestSuite(config: typeof testConfigs.svod, providerName: string, res
});

for (const field of fieldsWithPaths) {
I.seeElement(field.xpath);
I.waitForElement(field.xpath);
I.waitForValue(field.xpath, field.startingValue, 0);
I.fillField(field.xpath, field.newValue);
}
Expand Down
6 changes: 3 additions & 3 deletions test-e2e/tests/home_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Scenario('Header button navigates to playlist screen', async ({ I }) => {
Scenario('I can slide within the featured shelf', async ({ I }) => {
const isDesktop = await I.isDesktop();

async function slide(swipeText) {
async function slide(swipeText: string) {
if (isDesktop) {
I.click({ css: 'div[aria-label="Slide right"]' });
} else {
Expand All @@ -61,10 +61,9 @@ Scenario('I can slide within the featured shelf', async ({ I }) => {
I.see('8 min');
I.waitForInvisible('text="Blender Channel"', 3);
I.dontSee('Blender Channel');
I.dontSee('LIVE');

// Without this extra wait, the second slide action happens too fast after the first and even though the
// expected elements are present, the slide doesn't work. I think there must be a debounce on the carousel.
// expected elements are present, the slide doesn't work. I think there must be a debounce check on the carousel.
I.wait(1);

await slide('Spring');
Expand Down Expand Up @@ -132,6 +131,7 @@ Scenario('I can see the footer', ({ I }) => {
I.see('© JW Player');
I.see('jwplayer.com');
I.click('jwplayer.com');
I.wait(2);
I.switchToNextTab();
I.seeCurrentUrlEquals('https://jwplayer.com/');
});
3 changes: 2 additions & 1 deletion test-e2e/tests/language_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Scenario('Changing the language is persisted in the localStorage`', async ({ I }
});

Scenario('The language is restored from localStorage`', async ({ I }) => {
await I.restartBrowser({
I.restartBrowser({
storageState: {
origins: [
{
Expand Down Expand Up @@ -103,5 +103,6 @@ async function checkActiveLanguage(I: CodeceptJS.I, activeLanguage: keyof typeof
}

async function checkStyle(I: CodeceptJS.I, locator: CodeceptJS.LocatorOrString, styles: Record<string, string>) {
I.waitForElement(locator);
I.seeCssPropertiesOnElements(locator, styles);
}
11 changes: 5 additions & 6 deletions test-e2e/tests/payments/coupons_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,17 @@ function runTestSuite(props: ProviderProps, providerName: string) {
const today = new Date();

// This is written as a second test suite so that the login context is a different user.
// Otherwise there's no way to re-enter payment info and add a coupon code
// Otherwise, there's no way to re-enter payment info and add a coupon code
Feature(`payments-coupon - ${providerName}`).retry(Number(process.env.TEST_RETRY_COUNT) || 0);

Before(async ({ I }) => {
// This gets used in checkoutService.getOffer to make sure the offers are geolocated for NL
overrideIP(I);
I.useConfig(props.config);
couponLoginContext = await I.registerOrLogin(couponLoginContext);
});

Scenario(`I can redeem coupons - ${providerName}`, async ({ I }) => {
couponLoginContext = await I.registerOrLogin(couponLoginContext);

await goToCheckout(I);

I.click('Redeem coupon');
Expand Down Expand Up @@ -78,7 +77,7 @@ function runTestSuite(props: ProviderProps, providerName: string) {
I.see(formatPrice(0, 'EUR', props.locale));

if (props.shouldMakePayment) {
I.payWithCreditCard(
await I.payWithCreditCard(
props.paymentFields.creditCardholder,
props.creditCard,
props.paymentFields.cardNumber,
Expand All @@ -92,14 +91,14 @@ function runTestSuite(props: ProviderProps, providerName: string) {
});

Scenario(`I can cancel a free subscription - ${providerName}`, async ({ I }) => {
couponLoginContext = await I.registerOrLogin(couponLoginContext);
cancelPlan(I, addYear(today), props.canRenewSubscription, providerName);
});

Scenario(`I can renew a free subscription - ${providerName}`, async ({ I }) => {
if (props.canRenewSubscription) {
couponLoginContext = await I.registerOrLogin(couponLoginContext);
renewPlan(I, addYear(today), props.yearlyOffer.price);
} else {
I.say(`Provider ${providerName} does not support renewal. Skipping test...`);
}
});
}
Loading

0 comments on commit 4118327

Please sign in to comment.