Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add details page tests #247

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ export class MovieDetailPageUFO
await this.page.waitForSelector(heroImageSelector);
}

async getHeroImageSrc() {
await this.page.waitForSelector(heroImageSelector);
return await this.page.$$eval(heroImageSelector, async imgs => await imgs.map(img => img.getAttribute('src')).pop());
}

async awaitHeadingContent(): Promise<void> {
await Promise.all([
this.page.waitForSelector(heandlineSelector),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export class MovieListPageUFO extends Ufo implements CwvInterface {
]);
}

async awaitHeroImg() {
await this.movieList;
}

async awaitAllContent() {
await Promise.all([
this.awaitHeadingContent(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {UiMovieListUFO} from './ui-movie-list.ufo';
import {UiCastListUFO} from './ui-cast-list.ufo';
import {CwvInterface} from '../typings/cwv.interface';
import {BackNavigationInterface} from '../typings/back-navigation.interface';
import {backBtnSelector, heandlineSelector, heroImageSelector, subheandlineSelector} from '../../../../movies/testing';
import {Ufo, UserFlowContext} from '@push-based/user-flow';

export class PersonDetailPageUFO
extends Ufo
implements CwvInterface, BackNavigationInterface {
castList = new UiCastListUFO(this.ctx);
movieList = new UiMovieListUFO(this.ctx);

async navigateBack(): Promise<void> {
await this.page.waitForSelector(backBtnSelector);
await this.page.click(backBtnSelector);
}

async goToMovieDetail(id: number): Promise<void> {
await this.movieList.clickMovieListImage(id);
}

async awaitLCPContent(): Promise<void> {
await this.page.waitForSelector(heroImageSelector);
}

async getHeroImageSrc() {
await this.page.waitForSelector(heroImageSelector);
return await this.page.$$eval(heroImageSelector, async imgs => await imgs.map(img => img.getAttribute('src')).pop());
}

async awaitHeadingContent(): Promise<void> {
await Promise.all([
this.page.waitForSelector(heandlineSelector),
this.page.waitForSelector(subheandlineSelector),
]);
}

async awaitAllContent(): Promise<void> {
await Promise.all([
this.awaitLCPContent(),
this.awaitHeadingContent(),
this.movieList.awaitAllContent(),
this.castList.awaitAllContent(),
]);
}

constructor(private ctx: UserFlowContext) {
super(ctx);
}
}
2 changes: 2 additions & 0 deletions projects/movies/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@
"development": {
"verbose": true,
"dryRun": true,
"openReport": false,
"ufPath": "projects/movies/user-flows",
"serveCommand": "nx run movies:serve:development",
"awaitServeStdout": "Angular Live Development Server is listening on"
},
Expand Down
71 changes: 71 additions & 0 deletions projects/movies/user-flows/movie-details.uf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import {UserFlowContext, UserFlowInteractionsFn, UserFlowOptions, UserFlowProvider,} from '@push-based/user-flow';

import {mergeBudgets, MovieDetailPageUFO, MovieListPageUFO,} from '../../movies-user-flows/src';
import {getLhConfig} from "../../movies-user-flows/src/internals/test-sets";
import * as angularBudgets from "../testing/budgets/angular.budgets.json";
import * as generalTimingBudget from "../testing/budgets/general-timing.budgets.json";
import * as movieListBudgets from "../testing/budgets/movie-list.budgets.json";

const flowOptions: UserFlowOptions = {
name: 'Movie Detail Tests',
};

const interactions: UserFlowInteractionsFn = async (
ctx: UserFlowContext
): Promise<any> => {
const {flow, collectOptions} = ctx;
const url = `${collectOptions.url}/list/category/popular`;
const movieListPage = new MovieListPageUFO(ctx);
const movieDetailPage = new MovieDetailPageUFO(ctx);

await flow.navigate(url, {
stepName: '🧭 Initial navigation',
config: getLhConfig(
mergeBudgets([angularBudgets, generalTimingBudget, movieListBudgets])
)
});
await flow.snapshot({
stepName: '✔ Initial navigation done',
});


let currentHeroImageSrc = undefined;

// ======= Detail navigations =======
await flow.startTimespan({
stepName: '🧭 Navigate to detail page',
});
await movieListPage.navigateToDetail(1);
await movieDetailPage.awaitAllContent();
currentHeroImageSrc = await movieDetailPage.getHeroImageSrc();
await flow.endTimespan();
await flow.snapshot({
stepName: '✔ Navigation to detail page done',
});

// ======= Hero image change for recommendations =======

await flow.startTimespan({
stepName: '🧭 Navigate to other detail page',
});
await movieListPage.navigateToDetail(1);
await movieDetailPage.awaitAllContent();

const recommendationImageSrc = await movieDetailPage.getHeroImageSrc();
if (recommendationImageSrc === currentHeroImageSrc) {
throw new Error("hero image does not change when navigating to recommended movie!")
}
await flow.endTimespan();
await flow.snapshot({
stepName: '✔ Navigation to other detail page done',
});

return Promise.resolve();
};

export const userFlowProvider: UserFlowProvider = {
flowOptions,
interactions,
};

module.exports = userFlowProvider;
89 changes: 89 additions & 0 deletions projects/movies/user-flows/person-details.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import {UserFlowContext, UserFlowInteractionsFn, UserFlowOptions, UserFlowProvider,} from '@push-based/user-flow';

import {mergeBudgets, MovieDetailPageUFO, MovieListPageUFO,} from '../../movies-user-flows/src';
import {getLhConfig} from "../../movies-user-flows/src/internals/test-sets";
import * as angularBudgets from "../testing/budgets/angular.budgets.json";
import * as generalTimingBudget from "../testing/budgets/general-timing.budgets.json";
import * as movieListBudgets from "../testing/budgets/movie-list.budgets.json";
import {PersonDetailPageUFO} from "../../movies-user-flows/src/ufo/desktop/person-detail-page.ufo";

const flowOptions: UserFlowOptions = {
name: 'Person Detail Tests',
};

const interactions: UserFlowInteractionsFn = async (
ctx: UserFlowContext
): Promise<any> => {
const {flow, collectOptions, page} = ctx;
const url = `${collectOptions.url}/list/category/popular`;
const movieListPage = new MovieListPageUFO(ctx);
const movieDetailPage = new MovieDetailPageUFO(ctx);
const personDetailPage = new PersonDetailPageUFO(ctx);

await flow.navigate(url, {
stepName: '🧭 Initial navigation',
config: getLhConfig(
mergeBudgets([angularBudgets, generalTimingBudget, movieListBudgets])
)
});
await flow.snapshot({
stepName: '✔ Initial navigation done',
});

let currentHeroImageSrc = undefined;

// ======= Detail navigations =======
await flow.startTimespan({
stepName: '🧭 Navigate to person detail',
});

try {
await movieListPage.navigateToDetail(1);
await movieDetailPage.awaitAllContent();
await movieDetailPage.goToPersonDetail(1);
await personDetailPage.awaitAllContent();
} catch (e) {
await flow.endTimespan();
return Promise.resolve();
}

currentHeroImageSrc = await personDetailPage.getHeroImageSrc();
await flow.endTimespan();
await flow.snapshot({
stepName: '✔ Navigation to detail page done',
});

// ======= Hero image change for cast =======

await flow.startTimespan({
stepName: '🧭 Navigate to movie detail',
});
try {
await personDetailPage.goToMovieDetail(1);
await movieDetailPage.awaitAllContent();

const castImageSrc = await movieDetailPage.getHeroImageSrc();
if (castImageSrc === currentHeroImageSrc) {
throw new Error("Hero image does not change when navigating to cast!")
}

} catch (e) {

return Promise.resolve();

}

await flow.endTimespan();
await flow.snapshot({
stepName: '✔ Navigation to cast detail page done',
});

return Promise.resolve();
};

export const userFlowProvider: UserFlowProvider = {
flowOptions,
interactions,
};

module.exports = userFlowProvider;