Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Error’d: Pickup Sticklers

      September 27, 2025

      From Prompt To Partner: Designing Your Custom AI Assistant

      September 27, 2025

      Microsoft unveils reimagined Marketplace for cloud solutions, AI apps, and more

      September 27, 2025

      Design Dialects: Breaking the Rules, Not the System

      September 27, 2025

      Building personal apps with open source and AI

      September 12, 2025

      What Can We Actually Do With corner-shape?

      September 12, 2025

      Craft, Clarity, and Care: The Story and Work of Mengchu Yao

      September 12, 2025

      Cailabs secures €57M to accelerate growth and industrial scale-up

      September 12, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      Using phpinfo() to Debug Common and Not-so-Common PHP Errors and Warnings

      September 28, 2025
      Recent

      Using phpinfo() to Debug Common and Not-so-Common PHP Errors and Warnings

      September 28, 2025

      Mastering PHP File Uploads: A Guide to php.ini Settings and Code Examples

      September 28, 2025

      The first browser with JavaScript landed 30 years ago

      September 27, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured
      Recent
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»Web Development»A UX Review of Peugeot’s New Interior

    A UX Review of Peugeot’s New Interior

    July 1, 2025

    During a recent holiday, I got the new Peugeot 3008 in the rental car lottery. It features Peugeot’s new Panorama i-Cockpit—a bold dashboard redesign with a beautiful display. But after a week of use, it became clear that the software couldn’t match the impressive hardware.

    Source: Read More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleEgoDex: Learning Dexterous Manipulation from Large-Scale Egocentric Video
    Next Article The broken rhetoric of AI

    Related Posts

    Development

    PHP 8.5.0 RC 1 available for testing

    September 26, 2025
    Development

    Student Performance Prediction System using Python Machine Learning (ML)

    September 21, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    Proactive, Not Reactive – The Key to Inclusive and Accessible Design

    Development

    How to Read and Write Deeply Partitioned Files Using Apache Spark

    Development

    Critical Blink Router Flaws (CVSS 9.8) Allow Remote Root Code Execution via Unauthenticated Attacks

    Security

    Token Limit – Monitor token usage in AI context files

    Development

    Highlights

    Development

    How to Build a Custom Visual Testing Tool with Selenium: A Practical Guide

    June 25, 2025

    IntroductionVisual testing is crucial for ensuring UI consistency across releases. While commercial tools exist, sometimes you need a custom solution tailored to your specific needs. This guide walks you through creating your own visual testing tool using Selenium and Python.Table of ContentsIntroductionWhy Build a Custom Visual Testing Tool?Core ComponentsImplementation GuideAdvanced FeaturesIntegration & ScalingReporting & AnalysisCommon Challenges & SolutionsLimitations & ConsiderationsConclusion & Next StepsWhy Build a Custom Solution?Specific requirements not met by commercial toolsCost savings for simple projectsComplete control over comparison logicLearning opportunity about image processingCore Components1. Screenshot Capture with Seleniumpythonfrom selenium import webdriver
    import os

    def capture_screenshot(url, filename):
    “””Capture screenshot of a webpage”””
    driver = webdriver.Chrome()
    driver.get(url)

    # Ensure screenshot directory exists
    os.makedirs(“screenshots”, exist_ok=True)
    screenshot_path = f”screenshots/{filename}”

    driver.save_screenshot(screenshot_path)
    driver.quit()
    return screenshot_path2. Image Comparison Enginepythonfrom PIL import Image, ImageChops
    import math

    def compare_images(baseline_path, current_path, diff_path=None, threshold=0.95):
    “””
    Compare two images with similarity threshold
    Returns: (is_similar, similarity_score)
    “””
    baseline = Image.open(baseline_path).convert(‘RGB’)
    current = Image.open(current_path).convert(‘RGB’)

    # Check dimensions
    if baseline.size != current.size:
    return False, 0

    # Calculate difference
    diff = ImageChops.difference(baseline, current)
    diff_pixels = sum(
    sum(1 for pixel in diff.getdata() if any(c > 0 for c in pixel))
    )
    total_pixels = baseline.size[0] * baseline.size[1]
    similarity = 1 – (diff_pixels / total_pixels)

    # Save diff image if needed
    if diff_path and diff_pixels > 0:
    diff.save(diff_path)

    return similarity >= threshold, similarity3. Baseline Management Systempythonimport json
    from datetime import datetime

    class BaselineManager:
    def __init__(self, baseline_dir=”baselines”):
    self.baseline_dir = baseline_dir
    os.makedirs(baseline_dir, exist_ok=True)

    def save_baseline(self, name, image_path):
    “””Save a new baseline with metadata”””
    timestamp = datetime.now().isoformat()
    baseline_path = f”{self.baseline_dir}/{name}.png”
    metadata = {
    “created”: timestamp,
    “source”: image_path
    }

    # Save image
    Image.open(image_path).save(baseline_path)

    # Save metadata
    with open(f”{baseline_dir}/{name}.json”, ‘w’) as f:
    json.dump(metadata, f)

    return baseline_pathAdvanced Features1. Region-Specific Comparisonpythondef compare_regions(baseline_path, current_path, regions, threshold=0.95):
    “””
    Compare specific regions of images
    regions: List of (x, y, width, height) tuples
    “””
    baseline = Image.open(baseline_path)
    current = Image.open(current_path)
    results = []

    for region in regions:
    x, y, w, h = region
    baseline_crop = baseline.crop((x, y, x+w, y+h))
    current_crop = current.crop((x, y, x+w, y+h))

    is_similar, score = compare_images(
    baseline_crop, current_crop, threshold=threshold
    )
    results.append((region, is_similar, score))

    return results2. Dynamic Content Maskingpythondef mask_dynamic_regions(image_path, regions, output_path=None):
    “””
    Mask dynamic content regions with black rectangles
    “””
    img = Image.open(image_path)
    draw = ImageDraw.Draw(img)

    for region in regions:
    x, y, w, h = region
    draw.rectangle((x, y, x+w, y+h), fill=’black’)

    if output_path:
    img.save(output_path)
    return imgPutting It All Togetherpythondef run_visual_test(url, test_name, threshold=0.95):
    “””Complete visual test workflow”””
    # Setup
    bm = BaselineManager()
    current_path = capture_screenshot(url, f”current_{test_name}.png”)

    # Check if baseline exists
    baseline_path = f”baselines/{test_name}.png”
    if not os.path.exists(baseline_path):
    print(f”Creating new baseline for {test_name}”)
    bm.save_baseline(test_name, current_path)
    return True

    # Compare images
    diff_path = f”diffs/diff_{test_name}.png”
    is_similar, score = compare_images(
    baseline_path, current_path, diff_path, threshold
    )

    # Generate report
    report = {
    “test_name”: test_name,
    “passed”: is_similar,
    “similarity_score”: score,
    “diff_image”: diff_path if not is_similar else None,
    “timestamp”: datetime.now().isoformat()
    }

    return reportHandling Common ChallengesCross-Browser VariationsCreate separate baselines per browserAdjust similarity thresholds per browserResponsive TestingTest at multiple viewport sizesUse device emulation in SeleniumTest MaintenanceImplement baseline versioningAdd approval workflow for new baselinesPerformance OptimizationCache screenshotsParallelize testsIntegration with Test Frameworkspythonimport unittest

    class VisualTestCase(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
    cls.bm = BaselineManager()

    def test_homepage_layout(self):
    report = run_visual_test(
    “https://example.com”,
    “homepage_desktop”,
    threshold=0.98
    )
    self.assertTrue(report[‘passed’],
    f”Visual regression detected. Similarity: {report[‘similarity_score’]}”)Reporting and Analysispythondef generate_html_report(test_reports):
    “””Generate visual test HTML report”””
    html = “””
    <html><head><title>Visual Test Report</title></head>
    <body><h1>Visual Test Results</h1>
    <table border=”1″>
    <tr>
    <th>Test</th>
    <th>Status</th>
    <th>Similarity</th>
    <th>Diff</th>
    </tr>
    “””

    for report in test_reports:
    status = “PASS” if report[‘passed’] else “FAIL”
    color = “green” if report[‘passed’] else “red”
    diff_link = f'<a href=”{report[“diff_image”]}”>View</a>’ if report[“diff_image”] else “None”

    html += f”””
    <tr>
    <td>{report[‘test_name’]}</td>
    <td style=”color:{color}”>{status}</td>
    <td>{report[‘similarity_score’]:.2%}</td>
    <td>{diff_link}</td>
    </tr>
    “””

    html += “</table></body></html>”
    return htmlScaling Your SolutionParallel ExecutionUse Selenium GridImplement multiprocessingBaseline ManagementStore baselines in cloud storageAdd metadata taggingCI/CD IntegrationAdd as a test step in your pipelineConfigure failure thresholdsLimitations to ConsiderMaintenance overhead for baseline updatesBrowser-specific rendering differencesPerformance impact of image processingLimited to pixel comparison (no semantic understanding)ConclusionBuilding a custom visual testing tool gives you flexibility but requires careful implementation. Start small with critical pages, then expand as needed. Consider these enhancements:Add machine learning for smarter diff detectionImplement cloud storage for baselinesCreate a dashboard for trend analysisAdd support for component-level testingRemember that commercial tools might become more cost-effective as your needs grow, but a custom solution can be perfect for specific requirements.

    From Exploration Collapse to Predictable Limits: Shanghai AI Lab Proposes Entropy-Based Scaling Laws for Reinforcement Learning in LLMs

    June 3, 2025

    How to Improve Your Phone’s Privacy

    June 13, 2025

    Microsoft fixes Windows Server auth issues caused by April updates

    June 11, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.