Skip to content

Commit

Permalink
Merge pull request #345 from jwplayer/chore/seo-add-anchor-tag
Browse files Browse the repository at this point in the history
chore(project): add anchor tags for better seo
  • Loading branch information
olga-jwp authored Aug 3, 2023
2 parents 1330efa + b6c6df5 commit a754f56
Show file tree
Hide file tree
Showing 29 changed files with 162 additions and 121 deletions.
14 changes: 9 additions & 5 deletions src/components/Card/Card.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,22 @@ const itemWithImage = { title: 'This is a movie', duration: 120, cardImage: 'htt

describe('<Card>', () => {
it('renders card with video title', () => {
const { getByText } = renderWithRouter(<Card item={item} onClick={() => ''} />);
const { getByText } = renderWithRouter(<Card item={item} url="https://test.dummy.jwplayer.com" />);
expect(getByText(/aa/i)).toBeTruthy();
});

it('renders tag with correct duration', () => {
const { getByText } = renderWithRouter(<Card item={item} onClick={() => ''} />);
const { getByText } = renderWithRouter(<Card item={item} url="https://test.dummy.jwplayer.com" />);
expect(getByText(/2/i)).toBeTruthy();
});

it('renders the image with the image prop when valid', () => {
const { getByAltText } = renderWithRouter(<Card item={itemWithImage} onClick={() => ''} />);

const { getByAltText } = renderWithRouter(<Card item={itemWithImage} url="https://test.dummy.jwplayer.com" />);
expect(getByAltText('This is a movie')).toHaveAttribute('src', 'http://movie.jpg?width=320');
});

it('makes the image visible after load', () => {
const { getByAltText } = renderWithRouter(<Card item={itemWithImage} onClick={() => ''} />);
const { getByAltText } = renderWithRouter(<Card item={itemWithImage} url="https://test.dummy.jwplayer.com" />);

expect(getByAltText('This is a movie')).toHaveAttribute('src', 'http://movie.jpg?width=320');
expect(getByAltText('This is a movie')).toHaveStyle({ opacity: 0 });
Expand All @@ -36,4 +35,9 @@ describe('<Card>', () => {

expect(getByAltText('This is a movie')).toHaveStyle({ opacity: 1 });
});

it('should render anchor tag', () => {
const { container } = renderWithRouter(<Card item={itemWithImage} url="https://test.dummy.jwplayer.com" />);
expect(container).toMatchSnapshot();
});
});
12 changes: 4 additions & 8 deletions src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { KeyboardEvent, memo, useState } from 'react';
import React, { memo, useState } from 'react';
import classNames from 'classnames';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
Expand All @@ -19,7 +19,6 @@ export type PosterAspectRatio = (typeof cardAspectRatios)[number];

type CardProps = {
item: PlaylistItem;
onClick?: () => void;
onHover?: () => void;
progress?: number;
posterAspect?: PosterAspectRatio;
Expand All @@ -29,11 +28,10 @@ type CardProps = {
isCurrent?: boolean;
isLocked?: boolean;
currentLabel?: string;
url?: string;
url: string;
};

function Card({
onClick,
onHover,
progress,
item,
Expand Down Expand Up @@ -90,13 +88,11 @@ function Card({

return (
<Link
to={url ?? ''}
to={url}
className={cardClassName}
onClick={onClick}
onClick={disabled ? (e) => e.preventDefault() : undefined}
onMouseEnter={onHover}
tabIndex={disabled ? -1 : 0}
onKeyDown={(event: KeyboardEvent) => (event.key === 'Enter' || event.key === ' ') && !disabled && onClick && onClick()}
role="button"
aria-label={title}
>
<div className={posterClassNames}>
Expand Down
62 changes: 62 additions & 0 deletions src/components/Card/__snapshots__/Card.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`<Card> > should render anchor tag 1`] = `
<div>
<a
aria-label="This is a movie"
class="_card_d75732"
href="/https://test.dummy.jwplayer.com"
tabindex="0"
>
<div
class="_poster_d75732 _aspect169_d75732"
>
<img
alt="This is a movie"
class="_posterImage_d75732 _image_4c41c3"
src="http://movie.jpg?width=320"
/>
<div
class="_meta_d75732"
>
<div
class="_tags_d75732"
>
<div
aria-label="card_lock"
class="_tag_d75732 _lock_d75732"
role="status"
>
<svg
aria-hidden="true"
class="_icon_1e9999"
focusable="false"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12,17A2,2 0 0,0 14,15C14,13.89 13.1,13 12,13A2,2 0 0,0 10,15A2,2 0 0,0 12,17M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V10C4,8.89 4.9,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z"
fill="currentColor"
/>
</svg>
</div>
<div
class="_tag_d75732"
>
2 min
</div>
</div>
</div>
</div>
<div
class="_titleContainer_d75732"
>
<div
class="_title_d75732"
>
This is a movie
</div>
</div>
</a>
</div>
`;
4 changes: 2 additions & 2 deletions src/components/CardGrid/CardGrid.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import CardGrid from './CardGrid';

import playlistFixture from '#test/fixtures/playlist.json';
import { renderWithRouter } from '#test/testUtils';
import type { Playlist } from '#types/playlist';
import type { Playlist, PlaylistItem } from '#types/playlist';

describe('<CardGrid>', () => {
it('renders and matches snapshot', () => {
Expand All @@ -13,11 +13,11 @@ describe('<CardGrid>', () => {
<CardGrid
playlist={playlist}
onCardHover={vi.fn()}
onCardClick={vi.fn()}
isLoading={false}
accessModel={'SVOD'}
isLoggedIn={true}
hasSubscription={true}
getUrl={(item: PlaylistItem) => `https://test.dummy.jwplayer.com?media_id=${item.mediaid}`}
/>,
);

Expand Down
9 changes: 3 additions & 6 deletions src/components/CardGrid/CardGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import type { AccessModel } from '#types/Config';
import type { Playlist, PlaylistItem } from '#types/playlist';
import { parseAspectRatio, parseTilesDelta } from '#src/utils/collection';
import InfiniteScrollLoader from '#components/InfiniteScrollLoader/InfiniteScrollLoader';
import { mediaURL } from '#src/utils/formatting';

const INITIAL_ROW_COUNT = 6;
const LOAD_ROWS_COUNT = 4;
Expand All @@ -37,7 +36,7 @@ type CardGridProps = {
hasLoadMore?: boolean;
loadMore?: () => void;
onCardHover?: (item: PlaylistItem) => void;
onCardClick: (item: PlaylistItem, playlistId?: string) => void;
getUrl: (item: PlaylistItem) => string;
};

function CardGrid({
Expand All @@ -51,8 +50,8 @@ function CardGrid({
isLoggedIn,
hasSubscription,
hasLoadMore,
getUrl,
loadMore,
onCardClick,
onCardHover,
}: CardGridProps) {
const breakpoint: Breakpoint = useBreakpoint();
Expand All @@ -70,15 +69,13 @@ function CardGrid({

const renderTile = (playlistItem: PlaylistItem) => {
const { mediaid } = playlistItem;
const url = mediaURL({ media: playlistItem, playlistId: playlistItem.feedid });

return (
<div className={styles.cell} key={mediaid} role="row">
<div role="cell">
<Card
progress={watchHistory ? watchHistory[mediaid] : undefined}
url={url}
onClick={() => onCardClick(playlistItem, playlistItem.feedid)}
url={getUrl(playlistItem)}
onHover={typeof onCardHover === 'function' ? () => onCardHover(playlistItem) : undefined}
loading={isLoading}
isCurrent={currentCardItem && currentCardItem.mediaid === mediaid}
Expand Down
9 changes: 3 additions & 6 deletions src/components/CardGrid/__snapshots__/CardGrid.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ exports[`<CardGrid> > renders and matches snapshot 1`] = `
<a
aria-label="Agent 327"
class="_card_d75732"
href="/m/uB8aRnu6/agent-327?r=dGSUzs9o"
role="button"
href="/https://test.dummy.jwplayer.com?media_id=uB8aRnu6"
tabindex="0"
>
<div
Expand Down Expand Up @@ -60,8 +59,7 @@ exports[`<CardGrid> > renders and matches snapshot 1`] = `
<a
aria-label="Big Buck Bunny"
class="_card_d75732"
href="/m/awWEFyPu/big-buck-bunny?r=dGSUzs9o"
role="button"
href="/https://test.dummy.jwplayer.com?media_id=awWEFyPu"
tabindex="0"
>
<div
Expand Down Expand Up @@ -103,8 +101,7 @@ exports[`<CardGrid> > renders and matches snapshot 1`] = `
<a
aria-label="Elephants Dream"
class="_card_d75732"
href="/m/eFPH2tVG/elephants-dream?r=dGSUzs9o"
role="button"
href="/https://test.dummy.jwplayer.com?media_id=eFPH2tVG"
tabindex="0"
>
<div
Expand Down
1 change: 0 additions & 1 deletion src/components/Favorites/Favorites.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ describe('<Favorites>', () => {
playlist={playlist}
error={error}
isLoading={isLoading}
onCardClick={() => null}
onCardHover={() => null}
onClearFavoritesClick={() => null}
hasSubscription={true}
Expand Down
8 changes: 5 additions & 3 deletions src/components/Favorites/Favorites.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import ErrorPage from '#components/ErrorPage/ErrorPage';
import { Breakpoint, Breakpoints } from '#src/hooks/useBreakpoint';
import type { AccessModel } from '#types/Config';
import type { Playlist, PlaylistItem } from '#types/playlist';
import { mediaURL } from '#src/utils/formatting';

type Props = {
playlist: Playlist;
error: unknown;
isLoading: boolean;
accessModel: AccessModel;
hasSubscription: boolean;
onCardClick: (item: PlaylistItem) => void;
onCardHover?: (item: PlaylistItem) => void;
onClearFavoritesClick: () => void;
};
Expand All @@ -30,7 +30,7 @@ const cols: Breakpoints = {
[Breakpoint.xl]: 3,
};

const Favorites = ({ playlist, error, isLoading, accessModel, hasSubscription, onCardClick, onCardHover, onClearFavoritesClick }: Props): JSX.Element => {
const Favorites = ({ playlist, error, isLoading, accessModel, hasSubscription, onCardHover, onClearFavoritesClick }: Props): JSX.Element => {
const { t } = useTranslation('user');

if (isLoading) return <LoadingOverlay />;
Expand All @@ -39,6 +39,8 @@ const Favorites = ({ playlist, error, isLoading, accessModel, hasSubscription, o
return <ErrorPage title={t('favorites.not_found')} />;
}

const getURL = (playlistItem: PlaylistItem) => mediaURL({ media: playlistItem, playlistId: playlistItem.feedid });

return (
<div>
<div className={styles.header}>
Expand All @@ -47,8 +49,8 @@ const Favorites = ({ playlist, error, isLoading, accessModel, hasSubscription, o
</div>
{playlist.playlist.length > 0 ? (
<CardGrid
getUrl={getURL}
playlist={playlist}
onCardClick={onCardClick}
onCardHover={onCardHover}
cols={cols}
isLoading={isLoading}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Shelf/Shelf.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const Shelf = ({
isLocked={isLocked(accessModel, isLoggedIn, hasSubscription, item)}
posterAspect={posterAspect}
item={item}
url={isInView ? url : undefined}
url={url}
/>
);
},
Expand Down
17 changes: 4 additions & 13 deletions src/components/Shelf/__snapshots__/Shelf.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ exports[`Shelf Component tests > Featured shelf 1`] = `
<a
aria-label="Third movie"
class="_card_d75732 _featured_d75732 _disabled_d75732"
href="/"
role="button"
href="/m/12332123/third-movie"
tabindex="-1"
>
<div
Expand All @@ -67,8 +66,7 @@ exports[`Shelf Component tests > Featured shelf 1`] = `
<a
aria-label="Last playlist item"
class="_card_d75732 _featured_d75732 _disabled_d75732"
href="/"
role="button"
href="/m/ddeeddee/last-playlist-item"
tabindex="-1"
>
<div
Expand All @@ -92,7 +90,6 @@ exports[`Shelf Component tests > Featured shelf 1`] = `
aria-label="Movie 1"
class="_card_d75732 _featured_d75732"
href="/m/1234abcd/movie-1"
role="button"
tabindex="0"
>
<div
Expand Down Expand Up @@ -126,8 +123,7 @@ exports[`Shelf Component tests > Featured shelf 1`] = `
<a
aria-label="Movie 2"
class="_card_d75732 _featured_d75732 _disabled_d75732"
href="/"
role="button"
href="/m/aaaaaaaa/movie-2"
tabindex="-1"
>
<div
Expand All @@ -150,8 +146,7 @@ exports[`Shelf Component tests > Featured shelf 1`] = `
<a
aria-label="Third movie"
class="_card_d75732 _featured_d75732 _disabled_d75732"
href="/"
role="button"
href="/m/12332123/third-movie"
tabindex="-1"
>
<div
Expand Down Expand Up @@ -239,7 +234,6 @@ exports[`Shelf Component tests > Regular shelf 1`] = `
aria-label="Movie 1"
class="_card_d75732"
href="/m/1234abcd/movie-1"
role="button"
tabindex="0"
>
<div
Expand Down Expand Up @@ -278,7 +272,6 @@ exports[`Shelf Component tests > Regular shelf 1`] = `
aria-label="Movie 2"
class="_card_d75732"
href="/m/aaaaaaaa/movie-2"
role="button"
tabindex="0"
>
<div
Expand Down Expand Up @@ -317,7 +310,6 @@ exports[`Shelf Component tests > Regular shelf 1`] = `
aria-label="Third movie"
class="_card_d75732"
href="/m/12332123/third-movie"
role="button"
tabindex="0"
>
<div
Expand Down Expand Up @@ -356,7 +348,6 @@ exports[`Shelf Component tests > Regular shelf 1`] = `
aria-label="Last playlist item"
class="_card_d75732"
href="/m/ddeeddee/last-playlist-item"
role="button"
tabindex="0"
>
<div
Expand Down
Loading

0 comments on commit a754f56

Please sign in to comment.