Test Results (6 tests)
⏱️ Duration: 46.08s
❌ Error:
self = <tests.test_active_stock.TestActiveStock object at 0x7fded75bd300>
page = <Page url='https://promo.com/login'>, base_url = 'https://promo.com'
def test_as01_smoke_logged_in_create_page(self, page: Page, base_url: str) -> None:
"""Logged-in user on /active-cast sees header nav, curated catalog preview with category tags, recreate-btn on hover, and lands on /generate-from/."""
login_page = LoginPage(page)
> login_page.login_directly(base_url, general_mail(), get_password())
tests/test_active_stock.py:25:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
pages/login_page.py:116: in login_directly
self.page.wait_for_function(
/usr/local/lib/python3.10/dist-packages/playwright/sync_api/_generated.py:12761: in wait_for_function
self._sync(
/usr/local/lib/python3.10/dist-packages/playwright/_impl/_page.py:1151: in wait_for_function
return await self._main_frame.wait_for_function(**locals_to_params(locals()))
/usr/local/lib/python3.10/dist-packages/playwright/_impl/_frame.py:940: in wait_for_function
await self._channel.send("waitForFunction", self._timeout, params)
/usr/local/lib/python3.10/dist-packages/playwright/_impl/_connection.py:76: in send
return await self._connection.wrap_api_call(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <playwright._impl._connection.Connection object at 0x7fded75bfcd0>
cb = <function Channel.send.<locals>.<lambda> at 0x7fded6b13b50>
is_internal = False, title = None
async def wrap_api_call(
self, cb: Callable[[], Any], is_internal: bool = False, title: str = None
) -> Any:
if self._api_zone.get():
return await cb()
task = asyncio.current_task(self._loop)
parsed_st = _attach_api_call_information(
getattr(task, "__pw_stack__", None) or _capture_stack_trace(),
is_internal,
title,
)
self._api_zone.set(parsed_st)
📸 Failure Screenshot:
⏱️ Duration: 31.22s
❌ Error:
self = <tests.test_active_stock.TestActiveStock object at 0x7fded75beaa0>
page = <Page url='https://promo.com/activecast/my-videos'>
base_url = 'https://promo.com'
@pytest.mark.skip_smoke
def test_as03_my_videos_action_buttons(self, page: Page, base_url: str) -> None:
"""Logged-in user navigates to My Videos, confirms at least one video exists, and hovers to reveal action buttons."""
login_page = LoginPage(page)
login_page.login_directly(base_url, general_mail(), get_password())
login_page.assert_logged_in_as(fullname)
active_stock = ActiveStockPage(page)
active_stock.navigate_to_active_stock(base_url)
active_stock.go_to_my_videos()
active_stock.assert_has_at_least_one_video()
> active_stock.hover_first_video_and_assert_action_buttons()
tests/test_active_stock.py:57:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <pages.active_stock_page.ActiveStockPage object at 0x7fded5fd7790>
def hover_first_video_and_assert_action_buttons(self) -> None:
"""Hovers first video card and asserts recreate, delete and download buttons appear.
force=True: the My Videos grid keeps reflowing as thumbnails lazy-load,
so plain hover()'s stability check never settles and times out even
though the card is already visible. force=True skips that check and
dispatches the hover event directly at the element's location.
"""
first_video = self.page.locator(self.ITEM_ACTIVATE).first
first_video.wait_for(state="visible", timeout=self.T_ACTION)
first_video.hover(force=True)
for selector in [self.RECREATE_BTN, self.DELETE_PROJECT_BTN, self.DOWNLOAD_PROJECT_BTN]:
> expect(self.page.locator(selector).first).to_be_visible(timeout=self.T_ACTION)
E AssertionError: Locator expected to be visible
E Actual value: None
E Error: element(s) not found
E
📸 Failure Screenshot:
⏱️ Duration: 29.56s
❌ Error:
self = <tests.test_active_stock.TestActiveStock object at 0x7fded75bf610>
page = <Page url='https://promo.com/activecast/generate?imageId=2124945686&imageSource=shutterstock&imageTitle=Self+portrait+...lf-portrait-beautiful-young-afro-600nw-2124945686.jpg&term=happy&searchType=category&searchTerm=happy&searchRatio=all'>
base_url = 'https://promo.com'
@pytest.mark.skip_smoke
def test_as04_generate_page_controls_after_image_activation(self, page: Page, base_url: str) -> None:
"""Logged-in user activates an image from the create grid and verifies all generator controls are visible."""
login_page = LoginPage(page)
login_page.login_directly(base_url, general_mail(), get_password())
login_page.assert_logged_in_as(fullname)
active_stock = ActiveStockPage(page)
active_stock.navigate_to_create(base_url)
active_stock.assert_grid_has_at_least_20_items()
active_stock.hover_second_item_and_assert_activate_btn()
> active_stock.activate_image_and_assert_generate_page()
tests/test_active_stock.py:70:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <pages.active_stock_page.ActiveStockPage object at 0x7fdec7f17640>
def activate_image_and_assert_generate_page(self) -> None:
"""Clicks activate-image, then asserts URL, all generator controls visible, and crop/link controls absent."""
with self.page.expect_navigation(timeout=self.T_NETWORK):
self.page.locator(self.ACTIVATE_IMAGE_BTN).first.click(force=True)
# "networkidle" never resolves on this page (continuous analytics/chat-widget
# traffic), so rely on domcontentloaded plus the action-based waits below.
self.page.wait_for_load_state("domcontentloaded")
> assert "/active-cast/generate?imageId=" in self.page.url, (
f"Expected URL to contain '/active-cast/generate?imageId=', got: {self.page.url}"
)
E AssertionError: Expected
📸 Failure Screenshot:
⏱️ Duration: 44.43s
❌ Error:
self = <tests.test_active_stock.TestActiveStock object at 0x7fded75bdc90>
page = <Page url='https://promo.com/login'>, base_url = 'https://promo.com'
@pytest.mark.skip_smoke
def test_as06_upload_own_photo(self, page: Page, base_url: str) -> None:
"""Logged-in user uploads their own photo on the create page and lands on the generate page with it as the source image.
Upload Photo previously had an asymmetric rollout (present on prod/test05,
absent on test03), but as of 2026-09-06 the qaid probe confirms
upload-photo-btn/upload-photo-input are now present on test03 too, so the
skip has been removed.
"""
login_page = LoginPage(page)
> login_page.login_directly(base_url, general_mail(), get_password())
tests/test_active_stock.py:114:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
pages/login_page.py:116: in login_directly
self.page.wait_for_function(
/usr/local/lib/python3.10/dist-packages/playwright/sync_api/_generated.py:12761: in wait_for_function
self._sync(
/usr/local/lib/python3.10/dist-packages/playwright/_impl/_page.py:1151: in wait_for_function
return await self._main_frame.wait_for_function(**locals_to_params(locals()))
/usr/local/lib/python3.10/dist-packages/playwright/_impl/_frame.py:940: in wait_for_function
await self._channel.send("waitForFunction", self._timeout, params)
/usr/local/lib/python3.10/dist-packages/playwright/_impl/_connection.py:76: in send
return await self._connection.wrap_api_call(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <playwright._impl._connection.Connection object at 0x7fded75bfcd0>
cb = <function Channel.send.<locals>.<lambda> at 0x7fdec7ded990>
is_internal = False, title = None
async def wrap_api_call(
self, cb: Callable[[], Any], is_internal: bool = False, title: str = None
) -> Any:
if self._api_zone.get():
return awa
📸 Failure Screenshot: