diff --git a/app/(main)/player/page.tsx b/app/(main)/player/page.tsx index f319581..099cb8f 100644 --- a/app/(main)/player/page.tsx +++ b/app/(main)/player/page.tsx @@ -17,6 +17,8 @@ export default async function Page() {
diff --git a/app/tests/page.tsx b/app/tests/page.tsx index 5b375da..1bbdb95 100644 --- a/app/tests/page.tsx +++ b/app/tests/page.tsx @@ -5,6 +5,8 @@ export default function TestPage() { ); } diff --git a/app/ui/custom-link.tsx b/app/ui/custom-link.tsx index 755409a..101e036 100644 --- a/app/ui/custom-link.tsx +++ b/app/ui/custom-link.tsx @@ -21,6 +21,7 @@ export interface customLinkProps fontWeight?: number; bgClass?: string; hideTextOnMobile?: boolean; + onClick?: () => void; } /** @@ -60,6 +61,7 @@ export default function CustomLink({ blurring = false, fontWeight = 400, hideTextOnMobile, + onClick, ...anhorProps }: customLinkProps) { if (ico !== undefined && (alt === undefined || icoSize === undefined)) @@ -67,6 +69,7 @@ export default function CustomLink({ return ( (null); // Условия показывания многих элементов const conditions = !started || allSerias; + + useEffect(() => { + const player = ref.current; + if (!player) return undefined; + + const updateTime = () => setCurrentTime(player.currentTime); + player.addEventListener("time-update", updateTime); + + return () => { + player.removeEventListener("time-update", updateTime); + }; + }, []); + + const handleSkip = () => { + if (ref.current?.currentTime) { + ref.current.currentTime = openingTime; + } + return undefined; + }; + return ( + endTime ? "block" : "hidden"}`} + onClick={() => { + ref.current?.pause(); + }} + test-id="button: next_episode" + /> + + diff --git a/tests/conftest.py b/tests/conftest.py index 679cdd4..76f25b1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,6 +3,8 @@ from pages.main_page import MainPage from pages.sidebar_element import SideBar import pytest +import allure +import os def pytest_addoption(parser): parser.addoption('--stage', action='store', default=None, help="Choose stage: local or dev") @@ -53,7 +55,11 @@ def driver(request): else: """Обработка ситуации, если не указан стейдж""" raise pytest.UsageError("--stage should be local or dev") + yield driver + driver.delete_all_cookies() + driver.execute_script("window.localStorage.clear();") + driver.execute_script("window.sessionStorage.clear();") driver.quit() @pytest.fixture @@ -68,4 +74,25 @@ def sidebar(driver): def main_page(driver): return MainPage(driver) - \ No newline at end of file + +# делаем скриншот +@pytest.hookimpl(tryfirst=True, hookwrapper=True) +def pytest_runtest_makereport(item, call): + outcome = yield + rep = outcome.get_result() + if rep.when == 'call' and rep.failed: + mode = 'a' if os.path.exists('failures') else 'w' + try: + with open('failures', mode) as f: + if 'driver' in item.fixturenames: + web_driver = item.funcargs['driver'] + else: + print('Fail to take screen-shot') + return + allure.attach( + web_driver.get_screenshot_as_png(), + name='screenshot', + attachment_type=allure.attachment_type.PNG + ) + except Exception as e: + print('Fail to take screen-shot: {}'.format(e)) \ No newline at end of file diff --git a/tests/locators/player_page_locators.py b/tests/locators/player_page_locators.py index 04368f2..8292a57 100644 --- a/tests/locators/player_page_locators.py +++ b/tests/locators/player_page_locators.py @@ -85,6 +85,7 @@ class PlayerLocators: PLAY_VIDEOPLAYER = (By.XPATH, '//button[@class="player-module-scss-module__kFWiqG__start"]') BOTTOM_PLAYER_CONTAINER = (By.XPATH, '//div[@class="player-module-scss-module__kFWiqG__control"]') PLAYER_LOADER = (By.XPATH, '//div[@class="player-module-scss-module__kFWiqG__loader-container"]') + SKIP_OPENING_PLAYER = (By.CSS_SELECTOR, '[test-id="button: skip_opening"]') MINI_PLAY_BUTTON = (By.XPATH, '//div[@class="player-module-scss-module__kFWiqG__side"]//button[@class="player-module-scss-module__kFWiqG__plays"]') MINI_SKIP_BUTTON = (By.XPATH, '//div[@class="player-module-scss-module__kFWiqG__side"]//button[@class="player-module-scss-module__kFWiqG__skip"]') diff --git a/tests/pages/player_page.py b/tests/pages/player_page.py index 55991c2..19c1b5e 100644 --- a/tests/pages/player_page.py +++ b/tests/pages/player_page.py @@ -2,6 +2,7 @@ from locators.player_page_locators import PlayerLocators from locators.header_element_locators import HeaderElementLocators import random +from time import sleep from faker import Faker from selenium.webdriver.common.action_chains import ActionChains locators = PlayerLocators() @@ -221,21 +222,99 @@ def click_to_play_player(self): self.find(locators.PLAY_VIDEOPLAYER).click() self.element_is_not_visible(locators.PLAY_VIDEOPLAYER, 100) self.element_is_not_visible(locators.PLAYER_LOADER, 20) + # плеер всегд активный + self.player_always_is_active() + # ---------------------------- + self.click_to_skip_opening() #self.element_is_visible(locators.BOTTOM_PLAYER_CONTAINER, 20) УТОЧНИТЬ - assert self.find(locators.MINI_PLAY_BUTTON).get_attribute('aria-pressed') == "true", f'[Error] PlayerPage после нажатия на плеер не играет аниме. Стоит на паузе. Аттрибут aria_pressed = {self.find(locators.MINI_PLAY_BUTTON).get_attribute("aria-pressed")}' + #assert self.find(locators.MINI_PLAY_BUTTON).get_attribute('aria-pressed') == "true", f'[Error] PlayerPage после нажатия на плеер не играет аниме. Стоит на паузе. Аттрибут aria_pressed = {self.find(locators.MINI_PLAY_BUTTON).get_attribute("aria-pressed")}' + + def player_always_is_active(self): + script = """ +// Функция для поддержания элементов управления видимыми +function keepControlsVisible() { + // Находим основной элемент плеера + const player = document.querySelector('[data-media-player]'); + + if (!player) { + console.error('Плеер не найден'); + return; + } + + // Добавляем атрибуты, которые активируют элементы управления + player.setAttribute('data-focus', ''); + player.setAttribute('data-controls', ''); + + // Дополнительно делаем элементы видимыми через CSS + const style = document.createElement('style'); + style.innerHTML = ` + [data-media-player][data-controls] .player-module-scss-module__kFWiqG__control, + [data-media-player][data-focus] .player-module-scss-module__kFWiqG__control { + opacity: 1 !important; + visibility: visible !important; + pointer-events: auto !important; + } + + .player-module-scss-module__kFWiqG__darkness { + display: none !important; + } + `; + document.head.appendChild(style); + + // Регулярная проверка (на случай, если плеер удаляет атрибуты) + const intervalId = setInterval(() => { + if (!player.hasAttribute('data-focus')) { + player.setAttribute('data-focus', ''); + } + if (!player.hasAttribute('data-controls')) { + player.setAttribute('data-controls', ''); + } + }, 500); + + // Функция для остановки + window.stopKeepVisible = function() { + clearInterval(intervalId); + player.removeAttribute('data-focus'); + player.removeAttribute('data-controls'); + document.head.removeChild(style); + console.log('Скрипт остановлен. Элементы управления могут скрываться.'); + }; + + console.log('Элементы управления теперь всегда видны!'); + console.log('Для остановки введите: stopKeepVisible()'); +} + +// Запускаем скрипт +keepControlsVisible(); + +// Возвращаем true для подтверждения выполнения +return true; +""" + self.driver.execute_script(script) + self.element_is_visible(locators.CURRENT_TIME_PLAYER, 20) + + def click_to_skip_opening(self): + sleep(1) + self.element_is_clickable(locators.SKIP_OPENING_PLAYER, 10) + self.find(locators.SKIP_OPENING_PLAYER).click() + self.element_is_not_visible(locators.SKIP_OPENING_PLAYER, 10) def mouse_hover_to_player(self): - self.element_is_not_visible(locators.BOTTOM_PLAYER_CONTAINER, 20) + #self.element_is_not_visible(locators.BOTTOM_PLAYER_CONTAINER, 20) player = self.find(locators.VIDEOPLAYER_CONTAINER) actions = ActionChains(self.driver) actions.move_to_element(player).perform() self.element_is_visible(locators.BOTTOM_PLAYER_CONTAINER, 20) #assert self.find(locators.MINI_PLAY_BUTTON).get_attribute('aria-pressed') == "true", f'[Error] PlayerPage после нажатия на плеер не играет аниме. Стоит на паузе. Аттрибут aria_pressed = {self.find(locators.MINI_PLAY_BUTTON).get_attribute("aria-pressed")}' + def activate_player_desktop(self): + player = self.find(locators.VIDEOPLAYER_CONTAINER) + actions = ActionChains(self.driver) + actions.move_to_element(player).perform() + def click_to_setting_buttons(self): self.element_is_visible(locators.BOTTOM_PLAYER_CONTAINER, 20) self.element_is_clickable(locators.SETTINGS_BUTTON_PLAYER, 20) - self.mouse_hover_to_player() self.find(locators.SETTINGS_BUTTON_PLAYER).click() self.element_is_visible(locators.SETTINGS_WINDOW_CONTAINER, 20) @@ -264,14 +343,12 @@ def click_to_other_settings_button(self): assert self.find(locators.SETTINGS_AFTER_CLICK_H1).text == "Другие настройки", f'[Error] PlayerPage После нажатия на кнопку "Качество" открылся не тот поп ап, либо у него неверный H1. Фактический результа = {self.find(locators.SETTINGS_LANGUAGE_H1).text}' def click_to_subtitle_settings_button(self): - self.mouse_hover_to_player() self.element_is_clickable(locators.SETTINGS_SUBTITLE_BUTTON, 20) self.find(locators.SETTINGS_SUBTITLE_BUTTON).click() self.element_is_visible(locators.SETTINGS_AFTER_CLICK_WINDOW, 20) assert self.find(locators.SETTINGS_AFTER_CLICK_H1).text == "Субтитры", f'[Error] PlayerPage После нажатия на кнопку "Субтитры" открылся не тот поп ап, либо у него неверный H1. Фактический результа = {self.find(locators.SETTINGS_LANGUAGE_H1).text}' def click_to_more_volume_settings_button(self): - self.mouse_hover_to_player() self.element_is_clickable(locators.SETTINGS_MORE_VOLUME_BUTTON, 20) self.find(locators.SETTINGS_MORE_VOLUME_BUTTON).click() self.element_is_visible(locators.SETTINGS_AFTER_CLICK_WINDOW, 20) @@ -310,9 +387,10 @@ def activate_mobile_player(self): def click_to_play_player_mobile(self): self.check_player() self.find(locators.PLAY_VIDEOPLAYER).click() - self.activate_mobile_player() self.element_is_not_visible(locators.PLAY_VIDEOPLAYER, 20) self.element_is_clickable(locators.PLAY_BUTTON_MOBILE, 20) + self.player_always_is_active() + self.find(locators.SKIP_OPENING_PLAYER).click() self.element_is_clickable(locators.PREV_EPISODE_BUTTON_MOBILE, 20) self.element_is_clickable(locators.NEXT_EPISODE_BUTTON_MOBILE, 20) diff --git a/tests/test_player_page.py b/tests/test_player_page.py index 347c7e0..0ae5b8b 100644 --- a/tests/test_player_page.py +++ b/tests/test_player_page.py @@ -343,7 +343,9 @@ def test_quality_popup(driver): playerpage = PlayerPage(driver) playerpage.open('http://localhost:3001/player') playerpage.click_to_play_player() - playerpage.mouse_hover_to_player() + playerpage.player_always_is_active() + sleep(30) + #playerpage.mouse_hover_to_player() playerpage.click_to_setting_buttons() playerpage.click_to_quality_button()