mirror of
https://github.com/pretix/pretix.git
synced 2026-05-05 15:14:04 +00:00
236 lines
7.3 KiB
Python
236 lines
7.3 KiB
Python
"""
|
||
E2E Tests for Product Variations
|
||
|
||
Tests that verify items with variations (sizes, colors, etc.) work correctly:
|
||
- Expand/collapse behavior
|
||
- Price ranges
|
||
- Individual variation selection
|
||
- Auto-expand when filtered
|
||
"""
|
||
import pytest
|
||
from playwright.sync_api import Page, expect
|
||
|
||
|
||
@pytest.mark.django_db
|
||
class TestProductVariations:
|
||
"""Test product variation functionality."""
|
||
|
||
def test_item_with_variations_shows_toggle_button(
|
||
self,
|
||
page: Page,
|
||
live_server_url: str,
|
||
organizer,
|
||
event,
|
||
item_with_variations,
|
||
widget_page
|
||
):
|
||
"""
|
||
Item with variations should show expand/collapse button.
|
||
|
||
Variations should be collapsed by default with a button to expand them.
|
||
"""
|
||
item, variations = item_with_variations
|
||
|
||
widget_page.goto(live_server_url, organizer.slug, event.slug)
|
||
|
||
# Should show item name
|
||
expect(page.locator(f'text="{item.name}"')).to_be_visible()
|
||
|
||
# Should show variations toggle button
|
||
item_elem = page.locator(f'.pretix-widget-item:has-text("{item.name}")')
|
||
toggle_btn = item_elem.locator('button:has-text("variants"), button:has-text("Show variants")')
|
||
expect(toggle_btn.first).to_be_visible()
|
||
|
||
def test_expand_variations_on_click(
|
||
self,
|
||
page: Page,
|
||
live_server_url: str,
|
||
organizer,
|
||
event,
|
||
item_with_variations,
|
||
widget_page
|
||
):
|
||
"""
|
||
Clicking toggle button should expand variations.
|
||
|
||
After expanding, all variation options should be visible.
|
||
"""
|
||
item, variations = item_with_variations
|
||
|
||
widget_page.goto(live_server_url, organizer.slug, event.slug)
|
||
|
||
# Expand variations
|
||
widget_page.expand_variations(item.name)
|
||
|
||
# Wait for variations to be visible
|
||
page.wait_for_timeout(500) # Wait for animation
|
||
|
||
# All variations should now be visible
|
||
for variation in variations:
|
||
expect(page.locator(f'text="{variation.value}"')).to_be_visible()
|
||
|
||
def test_collapse_variations_on_second_click(
|
||
self,
|
||
page: Page,
|
||
live_server_url: str,
|
||
organizer,
|
||
event,
|
||
item_with_variations,
|
||
widget_page
|
||
):
|
||
"""Clicking toggle again should collapse variations."""
|
||
item, variations = item_with_variations
|
||
|
||
widget_page.goto(live_server_url, organizer.slug, event.slug)
|
||
|
||
item_elem = page.locator(f'.pretix-widget-item:has-text("{item.name}")')
|
||
toggle_btn = item_elem.locator('button:has-text("variants"), button:has-text("Show variants")')
|
||
|
||
# First click - expand
|
||
toggle_btn.first.click()
|
||
page.wait_for_timeout(500)
|
||
|
||
# Variations should be visible
|
||
for variation in variations:
|
||
expect(page.locator(f'text="{variation.value}"')).to_be_visible()
|
||
|
||
# Second click - collapse
|
||
toggle_btn.first.click()
|
||
page.wait_for_timeout(500)
|
||
|
||
# Variation inputs should no longer be visible
|
||
for variation in variations:
|
||
var_row = item_elem.locator(
|
||
f'.pretix-widget-variation:has(strong:text-is("{variation.value}"))')
|
||
expect(var_row.locator('input')).not_to_be_visible()
|
||
|
||
def test_price_range_for_collapsed_variations(
|
||
self,
|
||
page: Page,
|
||
live_server_url: str,
|
||
organizer,
|
||
event,
|
||
item_with_variations,
|
||
widget_page
|
||
):
|
||
"""
|
||
Collapsed variations should show price range.
|
||
|
||
When variations have different prices, should display range like "$20 - $30".
|
||
"""
|
||
item, variations = item_with_variations
|
||
|
||
widget_page.goto(live_server_url, organizer.slug, event.slug)
|
||
|
||
# Should show price range
|
||
# Variations go from $20 to $30
|
||
item_elem = page.locator(f'.pretix-widget-item:has-text("{item.name}")')
|
||
|
||
# Look for price range indicators
|
||
# Format is "EUR 20.00 – 30.00" in the main item's price box (first one)
|
||
price_box = item_elem.locator('.pretix-widget-pricebox').first
|
||
expect(price_box).to_contain_text('20.00')
|
||
expect(price_box).to_contain_text('30.00')
|
||
|
||
def test_select_variation_quantity(
|
||
self,
|
||
page: Page,
|
||
live_server_url: str,
|
||
organizer,
|
||
event,
|
||
item_with_variations,
|
||
widget_page
|
||
):
|
||
"""
|
||
User should be able to select quantity for specific variation.
|
||
|
||
After expanding variations, each should have its own quantity selector.
|
||
"""
|
||
item, variations = item_with_variations
|
||
|
||
widget_page.goto(live_server_url, organizer.slug, event.slug)
|
||
|
||
# Expand variations
|
||
widget_page.expand_variations(item.name)
|
||
page.wait_for_timeout(500)
|
||
|
||
# Select quantity for "Medium" variation
|
||
widget_page.select_variation_quantity(item.name, "Medium", 2)
|
||
|
||
# Verify input has the value
|
||
medium_var = page.locator('.pretix-widget-variation:has-text("Medium")')
|
||
input_field = medium_var.locator('input[type="number"]')
|
||
expect(input_field).to_have_value("2")
|
||
|
||
def test_variation_individual_prices(
|
||
self,
|
||
page: Page,
|
||
live_server_url: str,
|
||
organizer,
|
||
event,
|
||
item_with_variations,
|
||
widget_page
|
||
):
|
||
"""
|
||
Each variation should show its individual price.
|
||
|
||
When expanded, variations should display their specific prices.
|
||
"""
|
||
item, variations = item_with_variations
|
||
|
||
widget_page.goto(live_server_url, organizer.slug, event.slug)
|
||
|
||
# Expand variations
|
||
widget_page.expand_variations(item.name)
|
||
page.wait_for_timeout(500)
|
||
|
||
# Check each variation shows its price
|
||
variation_prices = {
|
||
'Small': '20.00',
|
||
'Medium': '25.00',
|
||
'Large': '25.00',
|
||
'X-Large': '30.00',
|
||
}
|
||
|
||
for var_name, price in variation_prices.items():
|
||
# Use exact heading match to avoid "Large" matching "X-Large"
|
||
var_elem = page.locator(
|
||
f'.pretix-widget-variation:has(strong:text-is("{var_name}"))'
|
||
)
|
||
expect(var_elem).to_be_visible()
|
||
# Price should be visible within the variation element
|
||
expect(var_elem.locator(f'text=/{price}/')).to_be_visible()
|
||
|
||
|
||
@pytest.mark.django_db
|
||
class TestVariationSubmission:
|
||
"""Test that variation selections submit correctly."""
|
||
|
||
def test_submit_with_variation_selection(
|
||
self,
|
||
page: Page,
|
||
live_server_url: str,
|
||
organizer,
|
||
event,
|
||
item_with_variations,
|
||
widget_page
|
||
):
|
||
"""Submitting with a variation selected should open iframe checkout."""
|
||
item, variations = item_with_variations
|
||
|
||
widget_page.goto(live_server_url, organizer.slug, event.slug)
|
||
|
||
# Expand and select a variation
|
||
widget_page.expand_variations(item.name)
|
||
page.wait_for_timeout(500)
|
||
widget_page.select_variation_quantity(item.name, "Large", 1)
|
||
|
||
widget_page.click_buy_button()
|
||
|
||
# Iframe checkout should open with the variation in the cart
|
||
widget_page.wait_for_iframe_checkout()
|
||
|
||
iframe_elem = page.locator('iframe[name^="pretix-widget-"]')
|
||
src = iframe_elem.get_attribute('src')
|
||
assert 'take_cart_id' in src
|