445 lines
18 KiB
Rust
445 lines
18 KiB
Rust
//! Shopping Workflow Tests
|
|
//!
|
|
//! Tests for complete shopping experience:
|
|
//! - Buy Now functionality
|
|
//! - Add to Cart workflow
|
|
//! - Checkout process
|
|
//! - Order confirmation
|
|
//! - Cart management (add, remove, edit quantities)
|
|
|
|
use crate::utils::*;
|
|
use crate::environment::*;
|
|
use tokio_test;
|
|
|
|
/// Test Buy Now complete workflow
|
|
#[tokio::test]
|
|
#[serial_test::serial]
|
|
async fn test_buy_now_complete_workflow() -> Result<(), Box<dyn std::error::Error>> {
|
|
let environment = TestFixtures::setup_test_environment().await?;
|
|
let mut helper = UXTestHelper::new(&environment);
|
|
|
|
log::info!("Testing Buy Now complete workflow");
|
|
|
|
// Login as consumer
|
|
let persona = helper.data_manager.get_persona(&UserRole::Consumer).unwrap();
|
|
helper.login_as(persona).await?;
|
|
|
|
// Navigate to marketplace
|
|
helper.browser.navigate_to("/marketplace").await?;
|
|
|
|
// Look for products with Buy Now option
|
|
if helper.browser.element_exists(".product-card, .product-item").await {
|
|
// Get initial wallet balance
|
|
let initial_balance = helper.api_client.get_wallet_balance().await.ok();
|
|
|
|
// Click on first product to get details
|
|
helper.browser.click(".product-card, .product-item").await?;
|
|
helper.browser.wait_for_element(".product-details, .buy-now").await.ok();
|
|
|
|
helper.take_screenshot("product_page_buy_now").await?;
|
|
|
|
// Click Buy Now button
|
|
if helper.browser.element_exists(".buy-now, button[data-action='buy-now']").await {
|
|
helper.browser.click(".buy-now, button[data-action='buy-now']").await?;
|
|
|
|
// Complete checkout flow
|
|
let order_id = helper.complete_checkout_flow().await?;
|
|
|
|
// Verify order confirmation
|
|
assert!(!order_id.is_empty());
|
|
helper.assert_element_contains_text(".order-confirmation, .success", "success").await.ok();
|
|
|
|
// Check if wallet balance was deducted (if we got initial balance)
|
|
if let Some(initial) = initial_balance {
|
|
let final_balance = helper.api_client.get_wallet_balance().await?;
|
|
assert!(final_balance.balance <= initial.balance, "Wallet balance should be deducted");
|
|
}
|
|
|
|
helper.take_screenshot("buy_now_success").await?;
|
|
}
|
|
}
|
|
|
|
log::info!("Buy Now complete workflow test completed successfully");
|
|
Ok(())
|
|
}
|
|
|
|
/// Test Add to Cart workflow
|
|
#[tokio::test]
|
|
#[serial_test::serial]
|
|
async fn test_add_to_cart_workflow() -> Result<(), Box<dyn std::error::Error>> {
|
|
let environment = TestFixtures::setup_test_environment().await?;
|
|
let mut helper = UXTestHelper::new(&environment);
|
|
|
|
log::info!("Testing Add to Cart workflow");
|
|
|
|
// Login as consumer
|
|
let persona = helper.data_manager.get_persona(&UserRole::Consumer).unwrap();
|
|
helper.login_as(persona).await?;
|
|
|
|
// Navigate to marketplace
|
|
helper.browser.navigate_to("/marketplace").await?;
|
|
|
|
// Initial cart should be empty or have known state
|
|
helper.navigate_to_cart().await?;
|
|
let initial_cart_items = helper.browser.find_elements(".cart-item, .product-item").await.unwrap_or_default().len();
|
|
|
|
// Go back to marketplace and add items
|
|
helper.browser.navigate_to("/marketplace").await?;
|
|
|
|
// Add first product to cart
|
|
if helper.browser.element_exists(".add-to-cart, .product-card").await {
|
|
helper.browser.click(".add-to-cart, .product-card .btn:not(.buy-now)").await?;
|
|
|
|
// Wait for cart update notification
|
|
helper.browser.wait_for_element(".cart-updated, .notification, .alert-success").await.ok();
|
|
helper.take_screenshot("item_added_to_cart").await?;
|
|
|
|
// Verify cart badge updated
|
|
if helper.browser.element_exists(".cart-badge, .cart-count").await {
|
|
let badge_text = helper.browser.get_text(".cart-badge, .cart-count").await?;
|
|
let cart_count = badge_text.parse::<usize>().unwrap_or(0);
|
|
assert!(cart_count > initial_cart_items, "Cart count should increase");
|
|
}
|
|
}
|
|
|
|
// Navigate to cart and verify item
|
|
helper.navigate_to_cart().await?;
|
|
let final_cart_items = helper.browser.find_elements(".cart-item, .product-item").await.unwrap_or_default().len();
|
|
assert!(final_cart_items > initial_cart_items, "Cart should have more items");
|
|
|
|
helper.take_screenshot("cart_with_added_items").await?;
|
|
|
|
log::info!("Add to Cart workflow test completed successfully");
|
|
Ok(())
|
|
}
|
|
|
|
/// Test cart management (edit quantities, remove items)
|
|
#[tokio::test]
|
|
#[serial_test::serial]
|
|
async fn test_cart_management() -> Result<(), Box<dyn std::error::Error>> {
|
|
let environment = TestFixtures::setup_test_environment().await?;
|
|
let mut helper = UXTestHelper::new(&environment);
|
|
|
|
log::info!("Testing cart management");
|
|
|
|
// Login as consumer
|
|
let persona = helper.data_manager.get_persona(&UserRole::Consumer).unwrap();
|
|
helper.login_as(persona).await?;
|
|
|
|
// Add items to cart first
|
|
helper.browser.navigate_to("/marketplace").await?;
|
|
|
|
// Add multiple items if possible
|
|
let add_to_cart_buttons = helper.browser.find_elements(".add-to-cart, .product-card .btn").await.unwrap_or_default();
|
|
for (i, button) in add_to_cart_buttons.iter().take(2).enumerate() {
|
|
button.click().await.ok();
|
|
helper.wait(std::time::Duration::from_millis(500)).await;
|
|
log::info!("Added item {} to cart", i + 1);
|
|
}
|
|
|
|
// Navigate to cart
|
|
helper.navigate_to_cart().await?;
|
|
|
|
// Test quantity editing (if available)
|
|
if helper.browser.element_exists(".quantity-input, input[name='quantity']").await {
|
|
helper.browser.type_text(".quantity-input, input[name='quantity']", "3").await?;
|
|
|
|
// Click update quantity button if exists
|
|
if helper.browser.element_exists(".update-quantity, .quantity-update").await {
|
|
helper.browser.click(".update-quantity, .quantity-update").await?;
|
|
helper.browser.wait_for_element(".cart-updated, .notification").await.ok();
|
|
}
|
|
|
|
helper.take_screenshot("cart_quantity_updated").await?;
|
|
}
|
|
|
|
// Test increase/decrease quantity buttons
|
|
if helper.browser.element_exists(".quantity-increase, .btn-plus").await {
|
|
helper.browser.click(".quantity-increase, .btn-plus").await?;
|
|
helper.wait(std::time::Duration::from_millis(500)).await;
|
|
helper.take_screenshot("cart_quantity_increased").await?;
|
|
}
|
|
|
|
if helper.browser.element_exists(".quantity-decrease, .btn-minus").await {
|
|
helper.browser.click(".quantity-decrease, .btn-minus").await?;
|
|
helper.wait(std::time::Duration::from_millis(500)).await;
|
|
helper.take_screenshot("cart_quantity_decreased").await?;
|
|
}
|
|
|
|
// Test remove item from cart
|
|
let initial_items = helper.browser.find_elements(".cart-item, .product-item").await.unwrap_or_default().len();
|
|
|
|
if helper.browser.element_exists(".remove-item, .delete-item, .btn-remove").await {
|
|
helper.browser.click(".remove-item, .delete-item, .btn-remove").await?;
|
|
|
|
// Wait for item removal
|
|
helper.browser.wait_for_element(".item-removed, .notification").await.ok();
|
|
|
|
// Verify item count decreased
|
|
let final_items = helper.browser.find_elements(".cart-item, .product-item").await.unwrap_or_default().len();
|
|
assert!(final_items < initial_items, "Cart items should decrease after removal");
|
|
|
|
helper.take_screenshot("cart_item_removed").await?;
|
|
}
|
|
|
|
// Test clear cart functionality
|
|
if helper.browser.element_exists(".clear-cart, .empty-cart").await {
|
|
helper.browser.click(".clear-cart, .empty-cart").await?;
|
|
|
|
// Handle confirmation if present
|
|
if helper.browser.element_exists(".confirm-clear, .confirm-yes").await {
|
|
helper.browser.click(".confirm-clear, .confirm-yes").await?;
|
|
}
|
|
|
|
// Verify cart is empty
|
|
helper.browser.wait_for_element(".cart-empty, .empty-state").await.ok();
|
|
helper.take_screenshot("cart_cleared").await?;
|
|
}
|
|
|
|
log::info!("Cart management test completed successfully");
|
|
Ok(())
|
|
}
|
|
|
|
/// Test complete checkout process
|
|
#[tokio::test]
|
|
#[serial_test::serial]
|
|
async fn test_complete_checkout_process() -> Result<(), Box<dyn std::error::Error>> {
|
|
let environment = TestFixtures::setup_test_environment().await?;
|
|
let mut helper = UXTestHelper::new(&environment);
|
|
|
|
log::info!("Testing complete checkout process");
|
|
|
|
// Login as consumer
|
|
let persona = helper.data_manager.get_persona(&UserRole::Consumer).unwrap();
|
|
helper.login_as(persona).await?;
|
|
|
|
// Add items to cart
|
|
helper.browser.navigate_to("/marketplace").await?;
|
|
if helper.browser.element_exists(".add-to-cart, .product-card").await {
|
|
helper.browser.click(".add-to-cart, .product-card .btn").await?;
|
|
helper.browser.wait_for_element(".cart-updated, .notification").await.ok();
|
|
}
|
|
|
|
// Navigate to cart
|
|
helper.navigate_to_cart().await?;
|
|
helper.take_screenshot("cart_before_checkout").await?;
|
|
|
|
// Get initial wallet balance for verification
|
|
let initial_balance = helper.api_client.get_wallet_balance().await.ok();
|
|
|
|
// Proceed to checkout
|
|
if helper.browser.element_exists(".checkout-btn, .proceed-checkout").await {
|
|
helper.browser.click(".checkout-btn, .proceed-checkout").await?;
|
|
|
|
// Wait for checkout page/modal
|
|
helper.browser.wait_for_element(".checkout, .checkout-form, .payment-form").await?;
|
|
helper.take_screenshot("checkout_page").await?;
|
|
|
|
// Fill checkout form if required
|
|
if helper.browser.element_exists("input[name='billing_address']").await {
|
|
helper.browser.type_text("input[name='billing_address']", "123 Test Street").await?;
|
|
}
|
|
|
|
if helper.browser.element_exists("input[name='city']").await {
|
|
helper.browser.type_text("input[name='city']", "Test City").await?;
|
|
}
|
|
|
|
// Confirm purchase
|
|
if helper.browser.element_exists(".confirm-purchase, .place-order").await {
|
|
helper.browser.click(".confirm-purchase, .place-order").await?;
|
|
|
|
// Wait for order processing
|
|
helper.browser.wait_for_element(".processing, .order-confirmation, .success").await?;
|
|
helper.take_screenshot("order_processing").await?;
|
|
|
|
// Wait for final confirmation
|
|
helper.browser.wait_for_element(".order-success, .purchase-complete").await?;
|
|
|
|
// Verify order details are displayed
|
|
if helper.browser.element_exists(".order-id, .order-number").await {
|
|
let order_id = helper.browser.get_text(".order-id, .order-number").await?;
|
|
assert!(!order_id.is_empty(), "Order ID should be displayed");
|
|
log::info!("Order completed with ID: {}", order_id);
|
|
}
|
|
|
|
helper.take_screenshot("checkout_success").await?;
|
|
|
|
// Verify wallet balance was deducted
|
|
if let Some(initial) = initial_balance {
|
|
let final_balance = helper.api_client.get_wallet_balance().await?;
|
|
assert!(final_balance.balance < initial.balance, "Wallet balance should be deducted");
|
|
log::info!("Wallet balance: {} -> {}", initial.balance, final_balance.balance);
|
|
}
|
|
}
|
|
}
|
|
|
|
log::info!("Complete checkout process test completed successfully");
|
|
Ok(())
|
|
}
|
|
|
|
/// Test checkout with insufficient funds
|
|
#[tokio::test]
|
|
#[serial_test::serial]
|
|
async fn test_checkout_insufficient_funds() -> Result<(), Box<dyn std::error::Error>> {
|
|
let environment = TestFixtures::setup_test_environment().await?;
|
|
let mut helper = UXTestHelper::new(&environment).await?;
|
|
|
|
log::info!("Testing checkout with insufficient funds");
|
|
|
|
// Login as consumer
|
|
let persona = helper.data_manager.get_persona(&UserRole::Consumer).unwrap();
|
|
helper.login_as(persona).await?;
|
|
|
|
// Check current wallet balance
|
|
let balance = helper.api_client.get_wallet_balance().await?;
|
|
|
|
// If balance is sufficient, we can't test insufficient funds scenario easily
|
|
// This test would need a way to set balance to insufficient amount
|
|
log::info!("Current balance: {} {}", balance.balance, balance.currency);
|
|
|
|
// Add expensive item to cart (if available) or multiple items
|
|
helper.browser.navigate_to("/marketplace").await?;
|
|
|
|
// Add items to cart until we might exceed balance
|
|
let products = helper.browser.find_elements(".product-card, .add-to-cart").await.unwrap_or_default();
|
|
for product in products.iter().take(5) {
|
|
product.click().await.ok();
|
|
helper.wait(std::time::Duration::from_millis(300)).await;
|
|
}
|
|
|
|
// Navigate to cart and try checkout
|
|
helper.navigate_to_cart().await?;
|
|
|
|
if helper.browser.element_exists(".checkout-btn").await {
|
|
helper.browser.click(".checkout-btn").await?;
|
|
|
|
// Look for insufficient funds error
|
|
helper.browser.wait_for_element(".insufficient-funds, .payment-error, .error").await.ok();
|
|
|
|
if helper.browser.element_exists(".insufficient-funds, .payment-error").await {
|
|
helper.take_screenshot("insufficient_funds_error").await?;
|
|
log::info!("Insufficient funds error properly displayed");
|
|
} else {
|
|
log::info!("No insufficient funds scenario encountered");
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Test order history and tracking
|
|
#[tokio::test]
|
|
#[serial_test::serial]
|
|
async fn test_order_history_and_tracking() -> Result<(), Box<dyn std::error::Error>> {
|
|
let environment = TestFixtures::setup_test_environment().await?;
|
|
let mut helper = UXTestHelper::new(&environment).await?;
|
|
|
|
log::info!("Testing order history and tracking");
|
|
|
|
// Login as consumer
|
|
let persona = helper.data_manager.get_persona(&UserRole::Consumer).unwrap();
|
|
helper.login_as(persona).await?;
|
|
|
|
// Navigate to order history
|
|
helper.navigate_to_dashboard_section("orders").await?;
|
|
|
|
// Verify orders page elements
|
|
assert!(helper.browser.element_exists(".orders, .order-history, .order-list").await);
|
|
helper.take_screenshot("order_history_page").await?;
|
|
|
|
// Check if orders exist
|
|
if helper.browser.element_exists(".order-item, .order-row").await {
|
|
// Click on first order for details
|
|
helper.browser.click(".order-item, .order-row").await?;
|
|
|
|
// Wait for order details
|
|
helper.browser.wait_for_element(".order-details, .order-info").await.ok();
|
|
helper.take_screenshot("order_details_page").await?;
|
|
|
|
// Verify order details elements
|
|
let expected_elements = vec![
|
|
".order-id, .order-number",
|
|
".order-date, .purchase-date",
|
|
".order-status, .status",
|
|
".order-total, .total-amount",
|
|
];
|
|
|
|
for element in expected_elements {
|
|
if helper.browser.element_exists(element).await {
|
|
log::info!("Found order detail element: {}", element);
|
|
}
|
|
}
|
|
|
|
// Test invoice download if available
|
|
if helper.browser.element_exists(".download-invoice, .invoice-link").await {
|
|
helper.browser.click(".download-invoice, .invoice-link").await?;
|
|
helper.take_screenshot("invoice_download").await?;
|
|
}
|
|
} else {
|
|
log::info!("No orders found in history - this is expected for new test environment");
|
|
}
|
|
|
|
log::info!("Order history and tracking test completed successfully");
|
|
Ok(())
|
|
}
|
|
|
|
/// Test different product categories checkout
|
|
#[tokio::test]
|
|
#[serial_test::serial]
|
|
async fn test_different_product_categories_checkout() -> Result<(), Box<dyn std::error::Error>> {
|
|
let environment = TestFixtures::setup_test_environment().await?;
|
|
let mut helper = UXTestHelper::new(&environment).await?;
|
|
|
|
log::info!("Testing different product categories checkout");
|
|
|
|
// Login as consumer
|
|
let persona = helper.data_manager.get_persona(&UserRole::Consumer).unwrap();
|
|
helper.login_as(persona).await?;
|
|
|
|
// Test different marketplace categories
|
|
let categories = vec![
|
|
"/marketplace/compute",
|
|
"/marketplace/applications",
|
|
"/marketplace/services",
|
|
];
|
|
|
|
for category_url in categories {
|
|
log::info!("Testing checkout for category: {}", category_url);
|
|
|
|
helper.browser.navigate_to(category_url).await?;
|
|
|
|
// Look for products in this category
|
|
if helper.browser.element_exists(".product-card, .service-item, .app-item").await {
|
|
// Try to add item to cart
|
|
helper.browser.click(".add-to-cart, .buy-now").await.ok();
|
|
|
|
// Handle any category-specific checkout flows
|
|
match category_url {
|
|
"/marketplace/compute" => {
|
|
// VM/Compute might have configuration options
|
|
if helper.browser.element_exists(".vm-config, .compute-options").await {
|
|
helper.take_screenshot("compute_configuration").await?;
|
|
}
|
|
}
|
|
"/marketplace/applications" => {
|
|
// Apps might have deployment options
|
|
if helper.browser.element_exists(".app-config, .deployment-options").await {
|
|
helper.take_screenshot("app_configuration").await?;
|
|
}
|
|
}
|
|
"/marketplace/services" => {
|
|
// Services might have booking/scheduling
|
|
if helper.browser.element_exists(".service-booking, .schedule-options").await {
|
|
helper.take_screenshot("service_booking").await?;
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
|
|
helper.wait(std::time::Duration::from_millis(500)).await;
|
|
}
|
|
}
|
|
|
|
log::info!("Different product categories checkout test completed successfully");
|
|
Ok(())
|
|
} |