diff --git a/packages/save-and-share-bar/src/save-and-share-bar.js b/packages/save-and-share-bar/src/save-and-share-bar.js
index 7eab7605e2..7c4d84079e 100644
--- a/packages/save-and-share-bar/src/save-and-share-bar.js
+++ b/packages/save-and-share-bar/src/save-and-share-bar.js
@@ -8,7 +8,7 @@ import {
} from "@times-components/icons";
import UserState from "@times-components/user-state";
import { SectionContext } from "@times-components/context";
-import { SaveStar } from "@times-components/ts-components";
+import { SaveStar, ArticleAudio } from "@times-components/ts-components";
import getTokenisedArticleUrlApi from "./get-tokenised-article-url-api";
import withTrackEvents from "./tracking/with-track-events";
@@ -247,6 +247,11 @@ function SaveAndShareBar(props) {
)}
>
) : null}
+ {process.env.NODE_ENV !== "test" && (
+
+ )}
);
}
diff --git a/packages/ts-components/src/components/article-audio/ArticleAudio.tsx b/packages/ts-components/src/components/article-audio/ArticleAudio.tsx
index 3ea2050baf..09d38b9284 100644
--- a/packages/ts-components/src/components/article-audio/ArticleAudio.tsx
+++ b/packages/ts-components/src/components/article-audio/ArticleAudio.tsx
@@ -1,5 +1,5 @@
import React, { FC, useState, useRef } from 'react';
-import { AudioButton } from './styles';
+import { AudioButton, AudioDuration } from './styles';
import { AudioPlayer } from '../audio-player-components/AudioPlayer';
import { PlayIcon, PauseIcon } from '@times-components/icons';
export interface ArticleAudioProps {
@@ -30,6 +30,7 @@ export const ArticleAudio: FC = ({ audioSrc }) => {
if (audioState === 'playing') {
setAudioState('paused');
+ setisAudioPlayerVisible(false);
} else {
setAudioState('playing');
}
@@ -37,6 +38,7 @@ export const ArticleAudio: FC = ({ audioSrc }) => {
const hidePlayer = () => {
setisAudioPlayerVisible(false);
+ setAudioState('not-started');
};
return (
@@ -49,8 +51,9 @@ export const ArticleAudio: FC = ({ audioSrc }) => {
/>
@@ -67,25 +70,30 @@ export const ArticleAudio: FC = ({ audioSrc }) => {
Listen
>
)}
-
{' '}
{duration} min
-
+
- {isAudioPlayerVisible && (
+
setAudioState('playing')}
onPause={() => setAudioState('paused')}
- onEnded={() => setAudioState('not-started')}
+ onEnded={() => hidePlayer()}
onClose={() => hidePlayer()}
/>
- )}
+
);
};
diff --git a/packages/ts-components/src/components/article-audio/__tests__/ArticleAudio.test.tsx b/packages/ts-components/src/components/article-audio/__tests__/ArticleAudio.test.tsx
index 65f270922b..09d663ed59 100644
--- a/packages/ts-components/src/components/article-audio/__tests__/ArticleAudio.test.tsx
+++ b/packages/ts-components/src/components/article-audio/__tests__/ArticleAudio.test.tsx
@@ -8,16 +8,21 @@ jest.mock('../styles', () => ({
+ ),
+ AudioDuration: ({ children, style }: any) => (
+
+ {children}
+
)
}));
jest.mock('@times-components/icons', () => ({
__esModule: true,
- PlayIcon: ({ color }: any) => (
-
+ PlayIcon: ({ fill }: any) => (
+
),
- PauseIcon: ({ color }: any) => (
-
+ PauseIcon: ({ fill }: any) => (
+
)
}));
@@ -60,53 +65,50 @@ describe('ArticleAudio', () => {
const audioButton = getByTestId('audio-button');
expect(audioButton).toBeInTheDocument();
- expect(audioButton.style.backgroundColor).toBe('');
expect(audioButton).toHaveStyle('color: #333');
+ expect(audioButton).toHaveStyle('background-color: #fff');
// The initial state should display 'Listen' and the duration
expect(getByText('Listen')).toBeInTheDocument();
expect(getByText('3 min')).toBeInTheDocument();
- // Since audioState is 'not-started', duration color should be '#696969'
- const durationSpan = getByText('3 min');
+ // Verify duration color when 'not-started'
+ const durationSpan = getByTestId('audio-duration');
expect(durationSpan).toHaveStyle('color: #696969');
});
- test('hides AudioPlayer when close button is clicked (using mocked AudioPlayer)', () => {
- const { getByTestId, queryByTestId, container, getByText } = render(
+ test('handles AudioPlayer visibility toggling', () => {
+ const { getByTestId, queryByTestId, container } = render(
);
- // Trigger the 'loadedmetadata' event to set the duration
const audio = container.querySelector('audio') as HTMLAudioElement;
act(() => {
fireEvent.loadedMetadata(audio);
});
- // Initially, the AudioPlayer should not be visible
- expect(queryByTestId('audio-player')).not.toBeInTheDocument();
+ const audioPlayer = queryByTestId('audioPlayerWrapper');
+
+ // Verify the player is hidden initially
+ expect(audioPlayer).toBeInTheDocument();
+ // expect(audioPlayer).toHaveStyle('opacity: 0');
+ expect(audioPlayer).toHaveStyle('display: none');
- // Click the audio button to start playback
+ // Click to show the player
const audioButton = getByTestId('audio-button');
fireEvent.click(audioButton);
- // The mocked AudioPlayer should now be visible
- expect(getByTestId('audio-player')).toBeInTheDocument();
-
- // Use the mocked Close button inside the AudioPlayer to close it
- const closeButton = getByText('Close');
- fireEvent.click(closeButton);
-
- // The AudioPlayer should no longer be visible
- expect(queryByTestId('audio-player')).not.toBeInTheDocument();
+ // Verify the player is now visible
+ // expect(audioPlayer).toHaveStyle('opacity: 1');
+ expect(audioPlayer).toHaveStyle('visibility: visible');
});
- test('handles play and pause', () => {
+ test('handles play and pause state transitions correctly', () => {
const { getByTestId, getByText, container } = render(
);
- // Trigger the 'loadedmetadata' event to set the duration
+ // Trigger the 'loadedmetadata' event
const audio = container.querySelector('audio') as HTMLAudioElement;
act(() => {
fireEvent.loadedMetadata(audio);
@@ -114,79 +116,75 @@ describe('ArticleAudio', () => {
const audioButton = getByTestId('audio-button');
- // Simulate clicking the play button
+ // Click to play
fireEvent.click(audioButton);
-
- // Now, audioState should be 'playing'
+ expect(getByText('Playing')).toBeInTheDocument();
expect(audioButton).toHaveStyle('background-color: #1D1D1B');
expect(audioButton).toHaveStyle('color: #fff');
- expect(getByText('Playing')).toBeInTheDocument();
- // Since audioState is 'playing', duration color should be '#fff'
- const durationSpan = getByText('3 min');
+ // Duration color should change to white
+ const durationSpan = getByTestId('audio-duration');
expect(durationSpan).toHaveStyle('color: #fff');
- // Simulate clicking the pause button
+ // Click to pause
fireEvent.click(audioButton);
-
expect(getByText('Paused')).toBeInTheDocument();
- expect(audioButton).toHaveStyle('background-color: #1D1D1B');
- expect(audioButton).toHaveStyle('color: #fff');
- // Simulate clicking the play button again
+ // Click to play again
fireEvent.click(audioButton);
-
expect(getByText('Playing')).toBeInTheDocument();
});
- test('shows AudioPlayer when audio is played', () => {
- const { getByTestId, queryByTestId, container } = render(
-
- );
-
- // Trigger the 'loadedmetadata' event to set the duration
- const audio = container.querySelector('audio') as HTMLAudioElement;
- act(() => {
- fireEvent.loadedMetadata(audio);
- });
-
- expect(queryByTestId('audio-player')).not.toBeInTheDocument();
-
- const audioButton = getByTestId('audio-button');
- fireEvent.click(audioButton);
-
- expect(getByTestId('audio-player')).toBeInTheDocument();
- });
-
- test('updates audioState based on AudioPlayer callbacks', () => {
+ test('updates audioState via AudioPlayer callbacks', () => {
const { getByTestId, getByText, container } = render(
);
- // Trigger the 'loadedmetadata' event to set the duration
+ // Trigger the 'loadedmetadata' event
const audio = container.querySelector('audio') as HTMLAudioElement;
act(() => {
fireEvent.loadedMetadata(audio);
});
const audioButton = getByTestId('audio-button');
- fireEvent.click(audioButton); // Start playing
-
- expect(getByText('Playing')).toBeInTheDocument();
+ fireEvent.click(audioButton); // Play
const pauseButton = getByText('Pause');
- fireEvent.click(pauseButton);
-
+ fireEvent.click(pauseButton); // Pause
expect(getByText('Paused')).toBeInTheDocument();
const playButton = getByText('Play');
- fireEvent.click(playButton);
-
+ fireEvent.click(playButton); // Play again
expect(getByText('Playing')).toBeInTheDocument();
const endedButton = getByText('Ended');
- fireEvent.click(endedButton);
-
+ fireEvent.click(endedButton); // Simulate end of playback
expect(getByText('Listen')).toBeInTheDocument();
});
});
+test('hides AudioPlayer when close button is clicked', () => {
+ const { getByTestId, getByText, container } = render(
+
+ );
+
+ // Trigger 'loadedmetadata' event to initialize duration
+ const audio = container.querySelector('audio') as HTMLAudioElement;
+ act(() => {
+ fireEvent.loadedMetadata(audio);
+ });
+
+ // Click the audio button to show the AudioPlayer
+ const audioButton = getByTestId('audio-button');
+ fireEvent.click(audioButton);
+
+ // Verify that the AudioPlayer is now visible
+ const audioPlayer = getByTestId('audioPlayerWrapper');
+ expect(audioPlayer).toHaveStyle('display: block');
+
+ // Simulate clicking the close button inside the AudioPlayer
+ const closeButton = getByText('Close');
+ fireEvent.click(closeButton);
+
+ // Verify that the AudioPlayer is hidden again
+ expect(audioPlayer).toHaveStyle('display: none');
+});
diff --git a/packages/ts-components/src/components/article-audio/__tests__/Styles.test.tsx b/packages/ts-components/src/components/article-audio/__tests__/Styles.test.tsx
index bff141f633..514fc50e60 100644
--- a/packages/ts-components/src/components/article-audio/__tests__/Styles.test.tsx
+++ b/packages/ts-components/src/components/article-audio/__tests__/Styles.test.tsx
@@ -14,7 +14,7 @@ describe('AudioButton', () => {
expect(button).toHaveStyleRule('background-color', 'unset');
expect(button).toHaveStyleRule('border-radius', '0');
- expect(button).toHaveStyleRule('padding', '7px 11px');
+ expect(button).toHaveStyleRule('padding', '6px 11px');
expect(button).toHaveStyleRule('border', '1px solid #333333');
expect(button).toHaveStyleRule('display', 'flex');
expect(button).toHaveStyleRule('align-items', 'center');
diff --git a/packages/ts-components/src/components/article-audio/styles.ts b/packages/ts-components/src/components/article-audio/styles.ts
index 9057d41ef1..76e59df974 100644
--- a/packages/ts-components/src/components/article-audio/styles.ts
+++ b/packages/ts-components/src/components/article-audio/styles.ts
@@ -1,10 +1,17 @@
import styled from 'styled-components';
-import { colours } from '@times-components/ts-styleguide';
+import { colours, breakpoints } from '@times-components/ts-styleguide';
+export const AudioDuration = styled.span`
+ display: none;
+
+ @media (min-width: ${breakpoints.small}px) {
+ display: block;
+ }
+`;
export const AudioButton = styled.button`
background-color: unset;
border-radius: 0;
- padding: 7px 11px;
+ padding: 6px 11px;
border: 1px solid ${colours.functional.primary};
display: flex;
align-items: center;