diff --git a/__tests__/Movie.test.tsx b/__tests__/Movie.test.tsx index e17cf66..b5ed53d 100644 --- a/__tests__/Movie.test.tsx +++ b/__tests__/Movie.test.tsx @@ -1,20 +1,60 @@ import Movie from 'app/movie/[id]'; -import { MOCK_MOVIE } from 'api/__mocks__/movie'; +import { MOCK_LOGO, MOCK_LOGO_EMPTY } from 'api/__mocks__/logo'; +import { MOCK_MOVIE, MOCK_MOVIE_WITH_NETWORK } from 'api/__mocks__/movie'; +import * as logo from '../src/api/logo'; import * as movie from '../src/api/movie'; -import { render, screen } from '../tests/render'; +import { mockQuery, render, screen } from '../tests/render'; describe('', () => { - test('Text renders correctly on HomeScreen', () => { + test('should render correctly', () => { + jest.spyOn(movie, 'useGetMovie').mockReturnValue(mockQuery(MOCK_MOVIE)); + jest.spyOn(logo, 'useGetContentLogo').mockReturnValue(mockQuery(MOCK_LOGO)); + + render(); + + expect(screen.getByTestId('release-date')).toHaveTextContent( + 'November 16, 2001' + ); + expect(screen.getByTestId('runtime')).toHaveTextContent('2h32m'); + expect(screen.getByTestId('votes')).toHaveTextContent('7.9 (26908)'); + expect(screen.queryByTestId('network-1234')).toBeFalsy(); + expect(screen.queryByTestId('subtitle')).toHaveTextContent( + 'Adventure - Fantasy' + ); + expect(screen.queryByTestId('cover-title')).toBeFalsy(); + expect(screen.queryByTestId('cover-image')).toHaveProp('source', { + uri: 'https://image.tmdb.org/t/p/w780/hziiv14OpD73u9gAak4XDDfBKa2.jpg' + }); + expect(screen.queryByTestId('cover-logo')).toHaveProp( + 'src', + 'https://image.tmdb.org/t/p/w500url-logo.png' + ); + }); + + test('should render correctly with network', () => { jest .spyOn(movie, 'useGetMovie') - .mockReturnValue(MOCK_MOVIE as movie.UseMovie); + .mockReturnValue(mockQuery(MOCK_MOVIE_WITH_NETWORK)); + jest.spyOn(logo, 'useGetContentLogo').mockReturnValue(mockQuery(MOCK_LOGO)); render(); - const textLabel = screen.getByTestId('release-date'); + expect(screen.getByTestId('network-213')).toBeTruthy(); + }); + + test('should render correctly without logo', () => { + jest.spyOn(movie, 'useGetMovie').mockReturnValue(mockQuery(MOCK_MOVIE)); + jest + .spyOn(logo, 'useGetContentLogo') + .mockReturnValue(mockQuery(MOCK_LOGO_EMPTY)); + + render(); - expect(textLabel).toHaveTextContent('June 20, 2024'); + expect(screen.queryByTestId('cover-title')).toHaveTextContent( + "Harry Potter and the Philosopher's Stone" + ); + expect(screen.queryByTestId('cover-logo')).toBeFalsy(); }); }); diff --git a/__tests__/person.test.tsx b/__tests__/person.test.tsx new file mode 100644 index 0000000..2a2f360 --- /dev/null +++ b/__tests__/person.test.tsx @@ -0,0 +1,55 @@ +import Person from 'app/person/[id]'; + +import { + MOCK_PERSON, + MOCK_PERSON_MOVIES, + MOCK_PERSON_TV +} from 'api/__mocks__/person'; + +import * as person from '../src/api/person'; +import { mockQuery, render, screen } from '../tests/render'; + +describe('', () => { + test('should render correctly', () => { + jest.spyOn(person, 'useGetPerson').mockReturnValue(mockQuery(MOCK_PERSON)); + jest + .spyOn(person, 'useGetPersonMovieCredits') + .mockReturnValue(mockQuery(MOCK_PERSON_MOVIES)); + jest + .spyOn(person, 'useGetPersonTvCredits') + .mockReturnValue(mockQuery(MOCK_PERSON_TV)); + + render(); + + expect(screen.getByTestId('department')).toHaveTextContent('Acting'); + expect(screen.getByTestId('birthday')).toHaveTextContent( + 'Born on July 23, 1989 (35y)' + ); + expect(screen.getByTestId('place-of-birth')).toHaveTextContent( + 'Hammersmith, London, England, UK' + ); + expect(screen.getByTestId('movies')).toHaveTextContent('1 movie'); + expect(screen.getByTestId('series')).toHaveTextContent('1 serie'); + expect(screen.queryByTestId('cover-title')).toHaveTextContent( + 'Daniel Radcliffe' + ); + expect(screen.queryByTestId('cover-image')).toHaveProp('source', { + uri: 'https://image.tmdb.org/t/p/w780/iPg0J9UzAlPj1fLEJNllpW9IhGe.jpg' + }); + }); + + test('should render correctly with deathday', () => { + jest + .spyOn(person, 'useGetPerson') + .mockReturnValue(mockQuery({ ...MOCK_PERSON, deathday: '2024-07-23' })); + + render(); + + expect(screen.getByTestId('birthday')).toHaveTextContent( + 'Born on July 23, 1989' + ); + expect(screen.getByTestId('deathday')).toHaveTextContent( + 'Died on July 23, 2024 (35y)' + ); + }); +}); diff --git a/__tests__/tv.test.tsx b/__tests__/tv.test.tsx new file mode 100644 index 0000000..277c035 --- /dev/null +++ b/__tests__/tv.test.tsx @@ -0,0 +1,56 @@ +import Tv from 'app/tv/[id]'; + +import { MOCK_LOGO, MOCK_LOGO_EMPTY } from 'api/__mocks__/logo'; +import { MOCK_TV, MOCK_TV_WITH_NETWORK } from 'api/__mocks__/tv'; + +import * as logo from '../src/api/logo'; +import * as tv from '../src/api/tv'; +import { mockQuery, render, screen } from '../tests/render'; + +describe('', () => { + test('should render correctly', () => { + jest.spyOn(tv, 'useGetTv').mockReturnValue(mockQuery(MOCK_TV)); + jest.spyOn(logo, 'useGetContentLogo').mockReturnValue(mockQuery(MOCK_LOGO)); + + render(); + + expect(screen.getByTestId('release-date')).toHaveTextContent('2022 - 2024'); + expect(screen.getByTestId('runtime')).toHaveTextContent('1h8m'); + expect(screen.getByTestId('votes')).toHaveTextContent('8.4 (4773)'); + expect(screen.queryByTestId('network-1234')).toBeFalsy(); + expect(screen.queryByTestId('subtitle')).toHaveTextContent( + 'Sci-Fi & Fantasy - Drama' + ); + expect(screen.queryByTestId('cover-title')).toBeFalsy(); + expect(screen.queryByTestId('cover-image')).toHaveProp('source', { + uri: 'https://image.tmdb.org/t/p/w780/etj8E2o0Bud0HkONVQPjyCkIvpv.jpg' + }); + expect(screen.queryByTestId('cover-logo')).toHaveProp( + 'src', + 'https://image.tmdb.org/t/p/w500url-logo.png' + ); + }); + + test('should render correctly with network', () => { + jest.spyOn(tv, 'useGetTv').mockReturnValue(mockQuery(MOCK_TV_WITH_NETWORK)); + jest.spyOn(logo, 'useGetContentLogo').mockReturnValue(mockQuery(MOCK_LOGO)); + + render(); + + expect(screen.getByTestId('network-49')).toBeTruthy(); + }); + + test('should render correctly without logo', () => { + jest.spyOn(tv, 'useGetTv').mockReturnValue(mockQuery(MOCK_TV)); + jest + .spyOn(logo, 'useGetContentLogo') + .mockReturnValue(mockQuery(MOCK_LOGO_EMPTY)); + + render(); + + expect(screen.queryByTestId('cover-title')).toHaveTextContent( + 'House of the Dragon' + ); + expect(screen.queryByTestId('cover-logo')).toBeFalsy(); + }); +}); diff --git a/maestro/discover.yml b/maestro/discover.yml new file mode 100644 index 0000000..ca77f3b --- /dev/null +++ b/maestro/discover.yml @@ -0,0 +1,52 @@ +appId: com.theomesnil.WhatToWatch +--- +- launchApp +- waitForAnimationToEnd +- takeScreenshot: 'maestro/screenshots/discover/index' +- tapOn: 'Discover' +- tapOn: + id: 'header-back-button' +- tapOn: + point: '14%,79%' +- tapOn: + id: 'header-back-button' +- scroll +- takeScreenshot: 'maestro/screenshots/discover/index2' +- tapOn: '1' +- tapOn: + id: 'header-back-button' +- tapOn: + point: '18%,52%' +- tapOn: + id: 'header-back-button' +- tapOn: 'Action Action' +- tapOn: + id: 'header-back-button' +- scroll +- takeScreenshot: 'maestro/screenshots/discover/index3' +- tapOn: + point: '33%,28%' +- tapOn: + id: 'header-back-button' +- tapOn: '1' +- tapOn: + id: 'header-back-button' +- tapOn: + point: '18%,84%' +- tapOn: + id: 'header-back-button' +- scroll +- takeScreenshot: 'maestro/screenshots/discover/index4' +- tapOn: 'Action & Adventure Action & Adventure' +- tapOn: + id: 'header-back-button' +- scroll +- takeScreenshot: 'maestro/screenshots/discover/index5' +- tapOn: + point: '33%,48%' +- tapOn: + id: 'header-back-button' +- tapOn: + point: '18%,78%' +- tapOn: + id: 'header-back-button' diff --git a/maestro/genre.yml b/maestro/genre.yml new file mode 100644 index 0000000..833358d --- /dev/null +++ b/maestro/genre.yml @@ -0,0 +1,35 @@ +appId: com.theomesnil.WhatToWatch +--- +- launchApp +- scroll +- scroll +- tapOn: 'Action Action' +- takeScreenshot: 'maestro/screenshots/genre/movie' +- tapOn: + point: '50%,31%' +- tapOn: + id: 'header-back-button' +- scroll +- takeScreenshot: 'maestro/screenshots/genre/movie2' +- tapOn: + point: '19%,26%' +- tapOn: + id: 'header-back-button' +- tapOn: + id: 'header-back-button' +- scroll +- scroll +- tapOn: 'Action & Adventure Action & Adventure' +- takeScreenshot: 'maestro/screenshots/genre/tv' +- tapOn: + point: '50%,31%' +- tapOn: + id: 'header-back-button' +- scroll +- takeScreenshot: 'maestro/screenshots/genre/tv2' +- tapOn: + point: '19%,26%' +- tapOn: + id: 'header-back-button' +- tapOn: + id: 'header-back-button' diff --git a/maestro/index.yml b/maestro/index.yml deleted file mode 100644 index 7a0ce69..0000000 --- a/maestro/index.yml +++ /dev/null @@ -1,7 +0,0 @@ -appId: com.theomesnil.WhatToWatch ---- -- launchApp -- waitForAnimationToEnd: - timeout: 5000 -- assertVisible: 'Top 10 series' -- takeScreenshot: 'maestro/screenshots/Home' diff --git a/maestro/movie.yml b/maestro/movie.yml index ad2d67a..e1ddcd9 100644 --- a/maestro/movie.yml +++ b/maestro/movie.yml @@ -2,6 +2,40 @@ appId: com.theomesnil.WhatToWatch --- - launchApp - tapOn: 'Search, tab, 2 of 3' -- waitForAnimationToEnd: - timeout: 5000 -- takeScreenshot: 'maestro/screenshots/Search' +- tapOn: 'What would you like to watch?' +- inputText: 'Harry potter philosopher' +- doubleTapOn: "Harry Potter and the Philosopher's Stone" +- waitForAnimationToEnd +- takeScreenshot: 'maestro/screenshots/movie/index' +- tapOn: 'Watch the trailer' +- assertVisible: + id: 'video' +- takeScreenshot: 'maestro/screenshots/movie/trailer' +- tapOn: + id: 'header-close-button' +- scroll +- takeScreenshot: 'maestro/screenshots/movie/index2' +- tapOn: 'Daniel Radcliffe Harry Potter' +- assertVisible: 'Daniel Radcliffe' +- tapOn: + id: 'header-back-button' +- tapOn: 'Official Trailer' +- takeScreenshot: 'maestro/screenshots/movie/video' +- tapOn: + id: 'header-close-button' +- scroll +- takeScreenshot: 'maestro/screenshots/movie/index3' +- tapOn: 'Backdrops' +- swipe: + direction: LEFT +- takeScreenshot: 'maestro/screenshots/movie/backdrops' +- tapOn: + id: 'header-close-button' +- tapOn: 'Posters' +- swipe: + direction: LEFT +- takeScreenshot: 'maestro/screenshots/movie/posters' +- tapOn: + id: 'header-close-button' +- tapOn: + id: 'header-back-button' diff --git a/maestro/network.yml b/maestro/network.yml new file mode 100644 index 0000000..27a9cb0 --- /dev/null +++ b/maestro/network.yml @@ -0,0 +1,21 @@ +appId: com.theomesnil.WhatToWatch +--- +- launchApp +- tapOn: 'Streaming, tab, 3 of 3' +- waitForAnimationToEnd +- takeScreenshot: 'maestro/screenshots/network/streaming' +- scroll +- takeScreenshot: 'maestro/screenshots/network/streaming2' +- tapOn: + point: '18%,78%' +- takeScreenshot: 'maestro/screenshots/network/index' +- tapOn: + point: '50%,31%' +- assertVisible: '2 seasons' +- tapOn: + id: 'header-back-button' +- scroll +- takeScreenshot: 'maestro/screenshots/network/index2' +- tapOn: + point: '50%,28%' +- assertVisible: '7 seasons' diff --git a/maestro/person.yml b/maestro/person.yml new file mode 100644 index 0000000..39c7009 --- /dev/null +++ b/maestro/person.yml @@ -0,0 +1,35 @@ +appId: com.theomesnil.WhatToWatch +--- +- launchApp +- tapOn: 'Search, tab, 2 of 3' +- tapOn: 'What would you like to watch?' +- inputText: 'Daniel Radcliffe' +- doubleTapOn: + point: '19%,38%' +- waitForAnimationToEnd +- takeScreenshot: 'maestro/screenshots/person/index' +- scroll +- takeScreenshot: 'maestro/screenshots/person/index2' +- tapOn: + point: '25%,42%' +- takeScreenshot: 'maestro/screenshots/person/know-for' +- tapOn: + id: 'header-back-button' +- tapOn: + id: 'credits-movie' +- takeScreenshot: 'maestro/screenshots/person/movies' +- tapOn: + id: 'header-back-button' +- tapOn: + id: 'credits-tv' +- takeScreenshot: 'maestro/screenshots/person/series' +- tapOn: + id: 'header-back-button' +- tapOn: + point: '18%,85%' +- swipe: + direction: LEFT +- takeScreenshot: 'maestro/screenshots/person/pictures' +- tapOn: + id: 'header-close-button' +- assertVisible: 'Pictures' diff --git a/maestro/screenshots/Home.png b/maestro/screenshots/Home.png deleted file mode 100644 index 5a2de46..0000000 Binary files a/maestro/screenshots/Home.png and /dev/null differ diff --git a/maestro/screenshots/Search.png b/maestro/screenshots/Search.png deleted file mode 100644 index 1f502f4..0000000 Binary files a/maestro/screenshots/Search.png and /dev/null differ diff --git a/maestro/screenshots/discover/index.png b/maestro/screenshots/discover/index.png new file mode 100644 index 0000000..fb3bb5b Binary files /dev/null and b/maestro/screenshots/discover/index.png differ diff --git a/maestro/screenshots/discover/index2.png b/maestro/screenshots/discover/index2.png new file mode 100644 index 0000000..4600d1a Binary files /dev/null and b/maestro/screenshots/discover/index2.png differ diff --git a/maestro/screenshots/discover/index3.png b/maestro/screenshots/discover/index3.png new file mode 100644 index 0000000..6a1a26a Binary files /dev/null and b/maestro/screenshots/discover/index3.png differ diff --git a/maestro/screenshots/discover/index4.png b/maestro/screenshots/discover/index4.png new file mode 100644 index 0000000..20f8a96 Binary files /dev/null and b/maestro/screenshots/discover/index4.png differ diff --git a/maestro/screenshots/discover/index5.png b/maestro/screenshots/discover/index5.png new file mode 100644 index 0000000..8e04a58 Binary files /dev/null and b/maestro/screenshots/discover/index5.png differ diff --git a/maestro/screenshots/genre/movie.png b/maestro/screenshots/genre/movie.png new file mode 100644 index 0000000..9cc5e48 Binary files /dev/null and b/maestro/screenshots/genre/movie.png differ diff --git a/maestro/screenshots/genre/movie2.png b/maestro/screenshots/genre/movie2.png new file mode 100644 index 0000000..7f240a6 Binary files /dev/null and b/maestro/screenshots/genre/movie2.png differ diff --git a/maestro/screenshots/genre/tv.png b/maestro/screenshots/genre/tv.png new file mode 100644 index 0000000..8dc9b4d Binary files /dev/null and b/maestro/screenshots/genre/tv.png differ diff --git a/maestro/screenshots/genre/tv2.png b/maestro/screenshots/genre/tv2.png new file mode 100644 index 0000000..0c5e979 Binary files /dev/null and b/maestro/screenshots/genre/tv2.png differ diff --git a/maestro/screenshots/movie/backdrops.png b/maestro/screenshots/movie/backdrops.png new file mode 100644 index 0000000..0ac2064 Binary files /dev/null and b/maestro/screenshots/movie/backdrops.png differ diff --git a/maestro/screenshots/movie/index.png b/maestro/screenshots/movie/index.png new file mode 100644 index 0000000..31c9610 Binary files /dev/null and b/maestro/screenshots/movie/index.png differ diff --git a/maestro/screenshots/movie/index2.png b/maestro/screenshots/movie/index2.png new file mode 100644 index 0000000..655be2e Binary files /dev/null and b/maestro/screenshots/movie/index2.png differ diff --git a/maestro/screenshots/movie/index3.png b/maestro/screenshots/movie/index3.png new file mode 100644 index 0000000..e5e04e8 Binary files /dev/null and b/maestro/screenshots/movie/index3.png differ diff --git a/maestro/screenshots/movie/posters.png b/maestro/screenshots/movie/posters.png new file mode 100644 index 0000000..e37c421 Binary files /dev/null and b/maestro/screenshots/movie/posters.png differ diff --git a/maestro/screenshots/movie/trailer.png b/maestro/screenshots/movie/trailer.png new file mode 100644 index 0000000..95bc1c5 Binary files /dev/null and b/maestro/screenshots/movie/trailer.png differ diff --git a/maestro/screenshots/movie/video.png b/maestro/screenshots/movie/video.png new file mode 100644 index 0000000..c0a3e0f Binary files /dev/null and b/maestro/screenshots/movie/video.png differ diff --git a/maestro/screenshots/network/index.png b/maestro/screenshots/network/index.png new file mode 100644 index 0000000..3cfef1c Binary files /dev/null and b/maestro/screenshots/network/index.png differ diff --git a/maestro/screenshots/network/index2.png b/maestro/screenshots/network/index2.png new file mode 100644 index 0000000..a2cd889 Binary files /dev/null and b/maestro/screenshots/network/index2.png differ diff --git a/maestro/screenshots/network/streaming.png b/maestro/screenshots/network/streaming.png new file mode 100644 index 0000000..99711c4 Binary files /dev/null and b/maestro/screenshots/network/streaming.png differ diff --git a/maestro/screenshots/network/streaming2.png b/maestro/screenshots/network/streaming2.png new file mode 100644 index 0000000..093a73f Binary files /dev/null and b/maestro/screenshots/network/streaming2.png differ diff --git a/maestro/screenshots/person/index.png b/maestro/screenshots/person/index.png new file mode 100644 index 0000000..41645ec Binary files /dev/null and b/maestro/screenshots/person/index.png differ diff --git a/maestro/screenshots/person/index2.png b/maestro/screenshots/person/index2.png new file mode 100644 index 0000000..8e525cf Binary files /dev/null and b/maestro/screenshots/person/index2.png differ diff --git a/maestro/screenshots/person/know-for.png b/maestro/screenshots/person/know-for.png new file mode 100644 index 0000000..bbc0cc6 Binary files /dev/null and b/maestro/screenshots/person/know-for.png differ diff --git a/maestro/screenshots/person/movies.png b/maestro/screenshots/person/movies.png new file mode 100644 index 0000000..01dca47 Binary files /dev/null and b/maestro/screenshots/person/movies.png differ diff --git a/maestro/screenshots/person/pictures.png b/maestro/screenshots/person/pictures.png new file mode 100644 index 0000000..e7776d4 Binary files /dev/null and b/maestro/screenshots/person/pictures.png differ diff --git a/maestro/screenshots/person/series.png b/maestro/screenshots/person/series.png new file mode 100644 index 0000000..73af68a Binary files /dev/null and b/maestro/screenshots/person/series.png differ diff --git a/maestro/screenshots/search/end.png b/maestro/screenshots/search/end.png new file mode 100644 index 0000000..100d8eb Binary files /dev/null and b/maestro/screenshots/search/end.png differ diff --git a/maestro/screenshots/search/index.png b/maestro/screenshots/search/index.png new file mode 100644 index 0000000..100d8eb Binary files /dev/null and b/maestro/screenshots/search/index.png differ diff --git a/maestro/screenshots/search/input.png b/maestro/screenshots/search/input.png new file mode 100644 index 0000000..13f96c2 Binary files /dev/null and b/maestro/screenshots/search/input.png differ diff --git a/maestro/screenshots/tv/backdrops.png b/maestro/screenshots/tv/backdrops.png new file mode 100644 index 0000000..060d299 Binary files /dev/null and b/maestro/screenshots/tv/backdrops.png differ diff --git a/maestro/screenshots/tv/casting.png b/maestro/screenshots/tv/casting.png new file mode 100644 index 0000000..65c97f0 Binary files /dev/null and b/maestro/screenshots/tv/casting.png differ diff --git a/maestro/screenshots/tv/index.png b/maestro/screenshots/tv/index.png new file mode 100644 index 0000000..2f2ecee Binary files /dev/null and b/maestro/screenshots/tv/index.png differ diff --git a/maestro/screenshots/tv/index2.png b/maestro/screenshots/tv/index2.png new file mode 100644 index 0000000..ecf09e5 Binary files /dev/null and b/maestro/screenshots/tv/index2.png differ diff --git a/maestro/screenshots/tv/index3.png b/maestro/screenshots/tv/index3.png new file mode 100644 index 0000000..e28aff8 Binary files /dev/null and b/maestro/screenshots/tv/index3.png differ diff --git a/maestro/screenshots/tv/index4.png b/maestro/screenshots/tv/index4.png new file mode 100644 index 0000000..1ff72ef Binary files /dev/null and b/maestro/screenshots/tv/index4.png differ diff --git a/maestro/screenshots/tv/index5.png b/maestro/screenshots/tv/index5.png new file mode 100644 index 0000000..07eae61 Binary files /dev/null and b/maestro/screenshots/tv/index5.png differ diff --git a/maestro/screenshots/tv/posters.png b/maestro/screenshots/tv/posters.png new file mode 100644 index 0000000..5ef2e88 Binary files /dev/null and b/maestro/screenshots/tv/posters.png differ diff --git a/maestro/screenshots/tv/trailer.png b/maestro/screenshots/tv/trailer.png new file mode 100644 index 0000000..3bdc00a Binary files /dev/null and b/maestro/screenshots/tv/trailer.png differ diff --git a/maestro/screenshots/tv/video.png b/maestro/screenshots/tv/video.png new file mode 100644 index 0000000..b6a3b91 Binary files /dev/null and b/maestro/screenshots/tv/video.png differ diff --git a/maestro/search.yml b/maestro/search.yml new file mode 100644 index 0000000..a727fa5 --- /dev/null +++ b/maestro/search.yml @@ -0,0 +1,36 @@ +appId: com.theomesnil.WhatToWatch +--- +- launchApp +- tapOn: 'Search, tab, 2 of 3' +- waitForAnimationToEnd +- takeScreenshot: 'maestro/screenshots/search/index' +- tapOn: 'What would you like to watch?' +- inputText: 'Harry potter philosopher' +- assertVisible: "Harry Potter and the Philosopher's Stone" +- takeScreenshot: 'maestro/screenshots/search/input' +# todo: fix this double tap +- doubleTapOn: "Harry Potter and the Philosopher's Stone" +- waitForAnimationToEnd +- assertVisible: "Harry Potter and the Philosopher's Stone" +- tapOn: + id: 'header-back-button' +- tapOn: + point: '92%,17%' +- tapOn: 'What would you like to watch?' +- inputText: 'Daniel radcli' +- doubleTapOn: 'Daniel radcliffe' +- waitForAnimationToEnd +- assertVisible: 'Daniel radcliffe' +- tapOn: + id: 'header-back-button' +- tapOn: + point: '92%,17%' +- inputText: 'Game of' +- doubleTapOn: 'Game of Thrones' +- waitForAnimationToEnd +- assertVisible: '8 seasons' +- tapOn: + id: 'header-back-button' +- tapOn: + point: '92%,17%' +- takeScreenshot: 'maestro/screenshots/search/end' diff --git a/maestro/tv.yml b/maestro/tv.yml new file mode 100644 index 0000000..c1734fb --- /dev/null +++ b/maestro/tv.yml @@ -0,0 +1,47 @@ +appId: com.theomesnil.WhatToWatch +--- +- launchApp +- tapOn: 'Search, tab, 2 of 3' +- tapOn: 'What would you like to watch?' +- inputText: 'House of the Dragon' +- doubleTapOn: + point: '19%,38%' +- waitForAnimationToEnd +- takeScreenshot: 'maestro/screenshots/tv/index' +- assertVisible: 'Watch on' +- tapOn: 'Watch the trailer' +- assertVisible: + id: 'video' +- takeScreenshot: 'maestro/screenshots/tv/trailer' +- tapOn: + id: 'header-close-button' +- scroll +- takeScreenshot: 'maestro/screenshots/tv/index2' +- tapOn: 'S2' +- takeScreenshot: 'maestro/screenshots/tv/index3' +- scroll +- scroll +- waitForAnimationToEnd +- takeScreenshot: 'maestro/screenshots/tv/index4' +- tapOn: 'Matt Smith Prince Daemon Targaryen' +- takeScreenshot: 'maestro/screenshots/tv/casting' +- tapOn: + id: 'header-back-button' +- scroll +- takeScreenshot: 'maestro/screenshots/tv/index5' +- tapOn: 'House of the Dragon Opening Credits 4K | Season 1 (HBO) | Game Of Thrones Extras' +- takeScreenshot: 'maestro/screenshots/tv/video' +- tapOn: + id: 'header-close-button' +- tapOn: 'Backdrops' +- swipe: + direction: LEFT +- takeScreenshot: 'maestro/screenshots/tv/backdrops' +- tapOn: + id: 'header-close-button' +- tapOn: 'Posters' +- swipe: + direction: LEFT +- takeScreenshot: 'maestro/screenshots/tv/posters' +- tapOn: + id: 'header-close-button' diff --git a/package.json b/package.json index 38638ca..c2ad537 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "lint:ts": "npx tsc --noEmit", "test": "jest --watchAll --coverage=false", "test:coverage": "jest", - "test:e2e": "maestro test maestro/", + "test:e2e": "rm -rf maestro/screenshots && maestro test maestro/", "test:ci": "jest --coverage=false --forceExit", "translate": "yarn extract-messages 'src/**/*.{tsx,ts}' -l en-US,fr-FR -o src/locales -d en-US --flat", "generate:api:types": "npx openapi-typescript https://developer.themoviedb.org/openapi/64542913e1f86100738e227f -o ./src/api/types.d.ts", diff --git a/src/api/__mocks__/logo.ts b/src/api/__mocks__/logo.ts new file mode 100644 index 0000000..b62413b --- /dev/null +++ b/src/api/__mocks__/logo.ts @@ -0,0 +1,8 @@ +import type { UseGetContentLogo } from 'api/logo'; + +export const MOCK_LOGO: UseGetContentLogo['data'] = { + url: 'url-logo.png', + aspectRatio: 245 / 234 +}; + +export const MOCK_LOGO_EMPTY: UseGetContentLogo['data'] = null; diff --git a/src/api/__mocks__/movie.ts b/src/api/__mocks__/movie.ts index bdcf76a..e5fee8a 100644 --- a/src/api/__mocks__/movie.ts +++ b/src/api/__mocks__/movie.ts @@ -1,20 +1,22 @@ +import type { UseGetMovie } from 'api/movie'; import { NETWORK_NETFLIX_ID } from 'constants/networks'; -import type { NetworkId } from 'types/content'; -export const MOCK_MOVIE = { - data: { - coverUrl: '/lgkPzcOSnTvjeMnuFzozRO5HHw1.jpg', - genres: 'Animation - Family', - networkLink: { - id: NETWORK_NETFLIX_ID as NetworkId, - link: 'link' - }, - overview: - 'Gru and Lucy and their girls—Margo, Edith and Agnes—welcome a new member to the Gru family, Gru Jr., who is intent on tormenting his dad. Gru also faces a new nemesis in Maxime Le Mal and his femme fatale girlfriend Valentina, forcing the family to go on the run.', - rating: { count: 840, votes: 7.4 }, - releaseDate: '2024-06-20', - runtime: 94, - tagline: 'Things just got a little more despicable.', - title: 'Despicable Me 4' +export const MOCK_MOVIE: UseGetMovie['data'] = { + coverUrl: '/hziiv14OpD73u9gAak4XDDfBKa2.jpg', + genres: 'Adventure - Fantasy', + overview: + "Harry Potter has lived under the stairs at his aunt and uncle's house his whole life. But on his 11th birthday, he learns he's a powerful wizard—with a place waiting for him at the Hogwarts School of Witchcraft and Wizardry. As he learns to harness his newfound powers with the help of the school's kindly headmaster, Harry uncovers the truth about his parents' deaths—and about the villain who's to blame.", + rating: { count: 26908, votes: 7.9 }, + releaseDate: '2001-11-16', + runtime: 152, + tagline: 'Let the magic begin.', + title: "Harry Potter and the Philosopher's Stone" +}; + +export const MOCK_MOVIE_WITH_NETWORK: UseGetMovie['data'] = { + ...MOCK_MOVIE, + networkLink: { + id: NETWORK_NETFLIX_ID, + link: 'link-to-network' } }; diff --git a/src/api/__mocks__/person.ts b/src/api/__mocks__/person.ts new file mode 100644 index 0000000..b7f905c --- /dev/null +++ b/src/api/__mocks__/person.ts @@ -0,0 +1,59 @@ +import type { UseGetPerson } from 'api/person'; + +export const MOCK_PERSON: UseGetPerson['data'] = { + biography: + "Daniel Jacob Radcliffe (born July 23, 1989) is an English actor. He rose to fame at age twelve, when he began portraying Harry Potter in the film series of the same name; and has held various other film and theatre roles. Over his career, Radcliffe has received various awards and nominations. Radcliffe made his acting debut at age 10 in the BBC One television film David Copperfield (1999), followed by his feature film debut in The Tailor of Panama (2001). The same year, he starred as Harry Potter in the film adaptation of the J.K. Rowling fantasy novel, Harry Potter and the Philosopher's Stone. Over the next decade, he played the eponymous role in seven sequels, culminating with Harry Potter and the Deathly Hallows – Part 2 (2011). During this period, he became one of the world's highest-paid actors and gained worldwide fame, popularity, and critical acclaim. Following the success of Harry Potter, Radcliffe starred in the romantic comedy What If? (2013), and played the lawyer Arthur Kipps in the horror film The Woman in Black (2012), poet Allen Ginsberg in the drama film Kill Your Darlings (2013), Igor in the science-fiction horror film Victor Frankenstein (2015), a sentient corpse in the comedy-drama film Swiss Army Man (2016), technological prodigy Walter Mabry in the heist thriller film Now You See Me 2 (2016), and FBI agent Nate Foster in the critically acclaimed thriller film Imperium (2016). Since 2019, he has starred in the TBS anthology series Miracle Workers. In 2022, he starred in the action comedy The Lost City and portrayed Weird Al Yankovic in Weird: The Al Yankovic Story. Radcliffe branched out to stage acting in 2007, starring in the West End and Broadway productions of Equus. From 2011 to 2012 he portrayed J. Pierrepont Finch in the Broadway revival of the musical How to Succeed in Business Without Really Trying. He continued in Martin McDonagh's dark comedy The Cripple of Inishmaan (2013-2014) in the West End and Broadway and a revival of Tom Stoppard's play Rosencrantz and Guildenstern Are Dead (2017) at The Old Vic. He also starred in the satirical plays Privacy (2016) and The Lifespan of a Fact (2018), respectively off and on Broadway. In 2022 starred in the New York Theatre Workshop revival of Stephen Sondheim's Merrily We Roll Along.", + birthday: '1989-07-23', + coverUrl: '/iPg0J9UzAlPj1fLEJNllpW9IhGe.jpg', + // @ts-ignore + deathday: null, + department: 'Acting', + name: 'Daniel Radcliffe', + placeOfBirth: 'Hammersmith, London, England, UK' +}; + +export const MOCK_PERSON_MOVIES = [ + { + adult: false, + backdrop_path: '/hziiv14OpD73u9gAak4XDDfBKa2.jpg', + character: 'Harry Potter', + credit_id: '52fe4267c3a36847f801be91', + genre_ids: [12, 14], + id: 671, + order: 0, + original_language: 'en', + original_title: "Harry Potter and the Philosopher's Stone", + overview: + "Harry Potter has lived under the stairs at his aunt and uncle's house his whole life. But on his 11th birthday, he learns he's a powerful wizard—with a place waiting for him at the Hogwarts School of Witchcraft and Wizardry. As he learns to harness his newfound powers with the help of the school's kindly headmaster, Harry uncovers the truth about his parents' deaths—and about the villain who's to blame.", + popularity: 183.788, + poster_path: '/wuMc08IPKEatf9rnMNXvIDxqP4W.jpg', + release_date: '2001-11-16', + title: "Harry Potter and the Philosopher's Stone", + video: false, + vote_average: 7.914, + vote_count: 26930 + } +]; + +export const MOCK_PERSON_TV = [ + { + adult: false, + backdrop_path: '/nABc2EP7CQWaODt8sJXmMfGs4v4.jpg', + character: 'Self - Guest', + credit_id: '525716a4760ee3776a149fe2', + episode_count: 2, + first_air_date: '2001-11-02', + genre_ids: [35, 10767], + id: 1834, + name: 'Friday Night with Jonathan Ross', + origin_country: ['GB'], + original_language: 'en', + original_name: 'Friday Night with Jonathan Ross', + overview: + "Jonathan Ross's take on current topics of conversation, guest interviews and live music from both a guest music group and the house band.", + popularity: 35.232, + poster_path: '/dweqcAMlpidmoJcLu4omwuwsnef.jpg', + vote_average: 5.8, + vote_count: 22 + } +]; diff --git a/src/api/__mocks__/tv.ts b/src/api/__mocks__/tv.ts new file mode 100644 index 0000000..ad252f8 --- /dev/null +++ b/src/api/__mocks__/tv.ts @@ -0,0 +1,55 @@ +import type { UseGetTv } from 'api/tv'; +import { NETWORK_HBO_ID } from 'constants/networks'; + +export const MOCK_TV: UseGetTv['data'] = { + coverUrl: '/etj8E2o0Bud0HkONVQPjyCkIvpv.jpg', + endYear: 2024, + genres: 'Sci-Fi & Fantasy - Drama', + name: 'House of the Dragon', + overview: + 'The Targaryen dynasty is at the absolute apex of its power, with more than 15 dragons under their yoke. Most empires crumble from such heights. In the case of the Targaryens, their slow fall begins when King Viserys breaks with a century of tradition by naming his daughter Rhaenyra heir to the Iron Throne. But when Viserys later fathers a son, the court is shocked when Rhaenyra retains her status as his heir, and seeds of division sow friction across the realm.', + rating: { count: 4773, votes: 8.4 }, + runtime: 68, + seasons: [ + { + air_date: '2022-08-21', + episode_count: 53, + id: 309556, + name: 'Specials', + overview: '', + poster_path: '/qVU4112Ob2ikHBu4VRC50MdWZcM.jpg', + season_number: 0, + vote_average: 0 + }, + { + air_date: '2022-08-20', + episode_count: 10, + id: 134965, + name: 'Season 1', + overview: '', + poster_path: '/m7ta0kNg2ONvnBFF76miVvbWK1V.jpg', + season_number: 1, + vote_average: 8 + }, + { + air_date: '2024-06-16', + episode_count: 8, + id: 368014, + name: 'Season 2', + overview: '', + poster_path: '/xhjADf5sslq7lbRjc50FgvIYIkT.jpg', + season_number: 2, + vote_average: 7.9 + } + ], + startYear: 2022, + tagline: 'All must choose.' +}; + +export const MOCK_TV_WITH_NETWORK: UseGetTv['data'] = { + ...MOCK_TV, + networkLink: { + id: NETWORK_HBO_ID, + link: 'link-to-network' + } +}; diff --git a/src/api/logo.ts b/src/api/logo.ts index 69f9889..a043ba8 100644 --- a/src/api/logo.ts +++ b/src/api/logo.ts @@ -1,3 +1,4 @@ +import type { UseQueryResult } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query'; import type { AxiosResponse } from 'axios'; import axios from 'axios'; @@ -37,7 +38,17 @@ function formatImageToLogo( : null; } -export function useGetContentLogo(props?: useGetContentLogoProps) { +export type UseGetContentLogo = UseQueryResult< + { + aspectRatio: number; + url: string; + } | null, + Error +>; + +export function useGetContentLogo( + props?: useGetContentLogoProps +): UseGetContentLogo { const { id, type } = props || {}; const locales = `${LOCALE},en`; diff --git a/src/api/movie.ts b/src/api/movie.ts index 90a014f..819881a 100644 --- a/src/api/movie.ts +++ b/src/api/movie.ts @@ -33,7 +33,7 @@ export type UseGetMovieEnabledApiProps = UseGetMovieApiProps & { enabled: boolean; }; -export type UseMovie = UseQueryResult< +export type UseGetMovie = UseQueryResult< { coverUrl?: string; genres: string; @@ -54,7 +54,7 @@ export type UseMovie = UseQueryResult< Error >; -export function useGetMovie(props?: UseGetMovieApiProps): UseMovie { +export function useGetMovie(props?: UseGetMovieApiProps): UseGetMovie { const { id } = props || {}; const { queryUrl } = getApi({ diff --git a/src/api/person.ts b/src/api/person.ts index b357419..cf51552 100644 --- a/src/api/person.ts +++ b/src/api/person.ts @@ -1,3 +1,4 @@ +import type { UseQueryResult } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query'; import type { AxiosResponse } from 'axios'; import axios from 'axios'; @@ -28,7 +29,20 @@ export type UseGetPersonWithDepartmentApiProps = UseGetPersonApiProps & { isActing: boolean; }; -export function useGetPerson(props?: UseGetPersonApiProps) { +export type UseGetPerson = UseQueryResult< + { + biography?: string; + birthday?: string; + coverUrl?: string; + deathday?: string; + department?: 'Acting' | 'Writing' | 'Director'; + name: string; + placeOfBirth?: string; + } | null, + Error +>; + +export function useGetPerson(props?: UseGetPersonApiProps): UseGetPerson { const { id } = props || {}; const { queryUrl } = getApi({ diff --git a/src/api/tv.ts b/src/api/tv.ts index bda0e73..1ab9e5f 100644 --- a/src/api/tv.ts +++ b/src/api/tv.ts @@ -1,3 +1,4 @@ +import type { UseQueryResult } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query'; import type { AxiosResponse } from 'axios'; import axios from 'axios'; @@ -38,7 +39,39 @@ export type UseGetTvWithSeasonApiProps = { seasonNumber: number; }; -export function useGetTv(props?: UseGetTvApiProps) { +export type UseGetTv = UseQueryResult< + { + coverUrl?: string; + endYear?: number; + genres?: string; + name: string; + networkLink?: { + id: NetworkId; + link: string; + }; + overview?: string; + rating?: { + count: number; + votes: number; + }; + runtime: number; + seasons: { + air_date: string; + episode_count: number; + id: number; + name: string; + overview: string; + poster_path?: string; + season_number: number; + vote_average: number; + }[]; + startYear?: number; + tagline?: string; + } | null, + Error +>; + +export function useGetTv(props?: UseGetTvApiProps): UseGetTv { const { id } = props || {}; const { queryUrl } = getApi({ diff --git a/src/app/movie/[id]/index.tsx b/src/app/movie/[id]/index.tsx index 3c185de..a1269fa 100644 --- a/src/app/movie/[id]/index.tsx +++ b/src/app/movie/[id]/index.tsx @@ -39,7 +39,6 @@ export default function Movie() { const movieID = Number(params?.id); const { data, isLoading } = useGetMovie({ id: movieID }); - const { data: logo, isLoading: isLoadingLogo } = useGetContentLogo({ id: movieID, type: 'movie' @@ -117,10 +116,12 @@ export default function Movie() { )} {!!runtime && ( - {formatTime(runtime)} + + {formatTime(runtime)} + )} {!!rating && ( - + {rating.votes} ({rating.count}) )} diff --git a/src/app/person/[id]/index.tsx b/src/app/person/[id]/index.tsx index 885f7bd..288c084 100644 --- a/src/app/person/[id]/index.tsx +++ b/src/app/person/[id]/index.tsx @@ -51,7 +51,6 @@ export default function Person() { id: personID, isActing }); - const { data: credits, isLoading: isLoadingCredits } = useGetPersonCredits({ id: personID, isActing @@ -92,9 +91,9 @@ export default function Person() { title={name} badges={ <> - {!!department && {department}} + {!!department && {department}} {!!birthday && ( - + <> {' '} )} {!!deathday && ( - + {' '} )} - {!!placeOfBirth && {placeOfBirth}} + {!!placeOfBirth && ( + {placeOfBirth} + )} {!!numberOfMovies && ( - + {numberOfMovies}{' '} {numberOfMovies === 1 && ( @@ -152,7 +153,7 @@ export default function Person() { )} {!!numberOfTvShows && ( - + {numberOfTvShows}{' '} {numberOfTvShows === 1 && ( diff --git a/src/app/person/components/CreditNumberThumb.tsx b/src/app/person/components/CreditNumberThumb.tsx index f51693d..0c420fe 100644 --- a/src/app/person/components/CreditNumberThumb.tsx +++ b/src/app/person/components/CreditNumberThumb.tsx @@ -17,7 +17,7 @@ export function CreditNumberThumb({ type }: CreditNumberThumbProps) { return ( - + {!!seasonsLength && ( - + {seasonsLength}{' '} {seasonsLength === 1 && ( @@ -149,16 +150,18 @@ export default function Tv() { )} {!!startYear && ( - + {startYear} {endYear && ` - ${endYear}`} )} {!!runtime && ( - {formatTime(runtime)} + + {formatTime(runtime)} + )} {!!rating && ( - + {rating.votes} ({rating.count}) )} diff --git a/src/app/video/[id].tsx b/src/app/video/[id].tsx index 48abe3b..f12cb86 100644 --- a/src/app/video/[id].tsx +++ b/src/app/video/[id].tsx @@ -1,5 +1,5 @@ import { useLocalSearchParams } from 'expo-router'; -import { Dimensions } from 'react-native'; +import { Dimensions, View } from 'react-native'; import YoutubePlayer from 'react-native-youtube-iframe'; import { theme } from 'theme'; @@ -18,12 +18,14 @@ export default function Video() { return ( - + + + ); } diff --git a/src/assets/icon.png b/src/assets/icon.png index 838ad14..c2bc991 100644 Binary files a/src/assets/icon.png and b/src/assets/icon.png differ diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx index 217615a..38cfc11 100644 --- a/src/components/Button/index.tsx +++ b/src/components/Button/index.tsx @@ -37,13 +37,14 @@ export const Button = React.forwardRef( onPress, size = 'md', style = {}, + testID, variant = 'primary', ...rest }, ref ) => { return ( - + = ({ {withBackButton && ( diff --git a/src/layouts/Content/index.tsx b/src/layouts/Content/index.tsx index 155a46e..8c0ae87 100644 --- a/src/layouts/Content/index.tsx +++ b/src/layouts/Content/index.tsx @@ -64,7 +64,7 @@ export function ContentLayout({ /> {badges && {badges}} - {subtitle && {subtitle}} + {subtitle && {subtitle}} {children} diff --git a/src/layouts/Modal/index.tsx b/src/layouts/Modal/index.tsx index 6b502ba..557e9d3 100644 --- a/src/layouts/Modal/index.tsx +++ b/src/layouts/Modal/index.tsx @@ -22,6 +22,7 @@ export default function ModalLayout({ children }: ModalLayoutProps) { style={[styles.header, isAndroid && { paddingTop: statusBarHeight }]} >