python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > pytest Playwright页面元素拖拽

使用pytest结合Playwright实现页面元素在两个区域间拖拽功能

作者:问道飞鱼

本文介绍了如何使用pytest结合Playwright实现页面元素在两个区域间的拖拽操作,通过创建一个简单的HTML页面和JavaScript代码来实现拖放功能,并使用Playwright的API来模拟和验证拖拽操作,需要的朋友可以参考下

好的,下面是使用 pytest 结合 Playwright 实现页面元素在两个区域间拖拽的完整示例。

这个示例将创建一个包含两个区域(sourcetarget)和一个可拖拽区块的 HTML 页面,然后使用 Playwright 模拟将该区块从一个区域拖拽到另一个区域的操作。

示例场景

我们将创建一个简单的 HTML 页面,包含:

  1. Source Area: 包含一个可拖拽的区块(例如一个带颜色的 <div>)。
  2. Target Area: 一个空的区域,用于接收被拖拽的区块。
  3. JavaScript: 实现 HTML5 拖放 API,处理 dragstart, dragover, 和 drop 事件,以便将元素从 source 移动到 target

1. 创建示例 HTML 页面 (drag_drop_block.html)

将以下 HTML 代码保存为 drag_drop_block.html 文件。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Block Drag & Drop Example</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 40px;
        }

        .area {
            width: 300px;
            height: 200px;
            border: 2px dashed #ccc;
            display: inline-block;
            vertical-align: top;
            margin: 20px;
            padding: 10px;
            position: relative;
        }

        #source-area {
            background-color: #e0f7fa; /* Light Blue */
        }

        #target-area {
            background-color: #f3e5f5; /* Light Purple */
        }

        .draggable-block {
            width: 100px;
            height: 100px;
            background-color: #f44336; /* Red */
            color: white;
            text-align: center;
            line-height: 100px; /* Vertically center text */
            cursor: move; /* Show move cursor */
            user-select: none; /* Prevent text selection */
            position: absolute; /* Position within parent */
            top: 30px;
            left: 50px;
        }

        .block-content {
            font-size: 12px;
        }

        /* Optional: Visual feedback during drag */
        .draggable-block.dragging {
            opacity: 0.5;
        }

        /* Success indicator */
        .success-indicator {
            color: green;
            font-weight: bold;
            display: none; /* Hidden initially */
        }

        #target-area.success .success-indicator {
            display: block;
        }
    </style>
</head>
<body>

    <h1>Block Drag & Drop Test</h1>

    <div id="source-area" class="area">
        <h3>Source Area</h3>
        <div id="draggable-block" class="draggable-block" draggable="true">
            <span class="block-content">Drag Me!</span>
        </div>
    </div>

    <div id="target-area" class="area">
        <h3>Target Area</h3>
        <p class="success-indicator">Block dropped successfully!</p>
    </div>

    <script>
        const draggableBlock = document.getElementById('draggable-block');
        const sourceArea = document.getElementById('source-area');
        const targetArea = document.getElementById('target-area');

        draggableBlock.addEventListener('dragstart', function(event) {
            event.dataTransfer.setData("text/plain", "block-id"); // Optional: Set data
            // Add a class for visual feedback
            this.classList.add('dragging');
        });

        draggableBlock.addEventListener('dragend', function(event) {
            // Remove visual feedback
            this.classList.remove('dragging');
        });

        targetArea.addEventListener('dragover', function(event) {
            event.preventDefault(); // Crucial: Allows dropping
        });

        targetArea.addEventListener('drop', function(event) {
            event.preventDefault(); // Crucial: Allows dropping

            // Move the block from source to target
            // We know the block is the only draggable element in source
            sourceArea.removeChild(draggableBlock);
            targetArea.appendChild(draggableBlock);

            // Optional: Add success class to target area
            targetArea.classList.add('success');
        });

        // Allow dropping back into source area too (for demo purposes)
        sourceArea.addEventListener('dragover', function(event) {
            event.preventDefault();
        });

        sourceArea.addEventListener('drop', function(event) {
            event.preventDefault();

            // Move the block from target back to source
            targetArea.removeChild(draggableBlock);
            sourceArea.appendChild(draggableBlock);

            // Remove success class from target area
            targetArea.classList.remove('success');
        });
    </script>

</body>
</html>

说明:

2. Pytest + Playwright 测试代码 (test_block_drag_drop.py)

首先,确保安装了必要的库:

pip install pytest playwright
playwright install

然后,将以下 Python 代码保存为 test_block_drag_drop.py

# test_block_drag_drop.py
import pytest
from playwright.sync_api import Page, expect

# Pytest fixture to provide a fresh browser page for each test
@pytest.fixture(scope="function")
def page(context):
    """Creates a new page for each test function."""
    page = context.new_page()
    yield page
    page.close()

def test_drag_block_from_source_to_target(page: Page):
    """
    Tests dragging a block from the source area to the target area.
    """
    # 1. Navigate to the HTML file
    # Update the path to point to where you saved the HTML file
    page.goto("file:///absolute/path/to/your/drag_drop_block.html")

    # 2. Define selectors for the draggable block and the target area
    source_area_selector = "#source-area"
    target_area_selector = "#target-area"
    draggable_block_selector = "#draggable-block"

    # 3. Verify initial state: block is in source area
    expect(page.locator(source_area_selector + " " + draggable_block_selector)).to_be_attached()
    expect(page.locator(target_area_selector + " " + draggable_block_selector)).not_to_be_attached()
    expect(page.locator(f"{target_area_selector} .success-indicator")).not_to_be_visible()

    # 4. Perform the drag and drop operation
    page.drag_and_drop(draggable_block_selector, target_area_selector)

    # 5. Verify final state: block is in target area
    expect(page.locator(target_area_selector + " " + draggable_block_selector)).to_be_attached(message="Block should be in target area after drop.")
    expect(page.locator(source_area_selector + " " + draggable_block_selector)).not_to_be_attached(message="Block should not be in source area after drop.")
    expect(page.locator(f"{target_area_selector} .success-indicator")).to_be_visible(message="Success indicator should be visible in target area.")

def test_drag_block_back_to_source(page: Page):
    """
    Tests dragging the block back from the target area to the source area.
    """
    # 1. Navigate to the HTML file
    page.goto("file:///absolute/path/to/your/drag_drop_block.html")

    # 2. Define selectors
    source_area_selector = "#source-area"
    target_area_selector = "#target-area"
    draggable_block_selector = "#draggable-block"

    # 3. First, move the block to the target area (using the previous test's logic or just do it here)
    # Initial state check
    expect(page.locator(source_area_selector + " " + draggable_block_selector)).to_be_attached()
    expect(page.locator(target_area_selector + " " + draggable_block_selector)).not_to_be_attached()

    # Drag to target first
    page.drag_and_drop(draggable_block_selector, target_area_selector)

    # Confirm it's in target
    expect(page.locator(target_area_selector + " " + draggable_block_selector)).to_be_attached()
    expect(page.locator(source_area_selector + " " + draggable_block_selector)).not_to_be_attached()
    expect(page.locator(f"{target_area_selector} .success-indicator")).to_be_visible()

    # 4. Now, drag the block back from target to source
    page.drag_and_drop(draggable_block_selector, source_area_selector)

    # 5. Verify final state: block is back in source area
    expect(page.locator(source_area_selector + " " + draggable_block_selector)).to_be_attached(message="Block should be back in source area after second drop.")
    expect(page.locator(target_area_selector + " " + draggable_block_selector)).not_to_be_attached(message="Block should not be in target area after second drop.")
    expect(page.locator(f"{target_area_selector} .success-indicator")).not_to_be_visible(message="Success indicator should be hidden after moving block back to source.")

说明:

3. 运行测试

在终端中,切换到包含 test_block_drag_drop.pydrag_drop_block.html 的目录,然后运行:

pytest test_block_drag_drop.py -v

如果配置正确,你应该会看到类似以下的输出,并且浏览器窗口会短暂出现以执行测试:

============================= test session starts ==============================
platform linux -- Python 3.x.y, pytest-x.x.x, pluggy-x.x.x
rootdir: /path/to/your/test/directory
collected 2 items

test_block_drag_drop.py::test_drag_block_from_source_to_target PASSED    [ 50%]
test_block_drag_drop.py::test_drag_block_back_to_source PASSED           [100%]

============================== 2 passed in 3.12s ===============================

这表明两个测试(从 source 到 target,以及从 target 回到 source)都成功通过了。

以上就是使用pytest结合Playwright实现页面元素在两个区域间拖拽功能的详细内容,更多关于pytest Playwright页面元素拖拽的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文