最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用pytest結(jié)合Playwright實(shí)現(xiàn)頁(yè)面元素在兩個(gè)區(qū)域間拖拽功能

 更新時(shí)間:2026年01月23日 09:53:55   作者:?jiǎn)柕里w魚  
本文介紹了如何使用pytest結(jié)合Playwright實(shí)現(xiàn)頁(yè)面元素在兩個(gè)區(qū)域間的拖拽操作,通過(guò)創(chuàng)建一個(gè)簡(jiǎn)單的HTML頁(yè)面和JavaScript代碼來(lái)實(shí)現(xiàn)拖放功能,并使用Playwright的API來(lái)模擬和驗(yàn)證拖拽操作,需要的朋友可以參考下

好的,下面是使用 pytest 結(jié)合 Playwright 實(shí)現(xiàn)頁(yè)面元素在兩個(gè)區(qū)域間拖拽的完整示例。

這個(gè)示例將創(chuàng)建一個(gè)包含兩個(gè)區(qū)域(sourcetarget)和一個(gè)可拖拽區(qū)塊的 HTML 頁(yè)面,然后使用 Playwright 模擬將該區(qū)塊從一個(gè)區(qū)域拖拽到另一個(gè)區(qū)域的操作。

示例場(chǎng)景

我們將創(chuàng)建一個(gè)簡(jiǎn)單的 HTML 頁(yè)面,包含:

  1. Source Area: 包含一個(gè)可拖拽的區(qū)塊(例如一個(gè)帶顏色的 <div>)。
  2. Target Area: 一個(gè)空的區(qū)域,用于接收被拖拽的區(qū)塊。
  3. JavaScript: 實(shí)現(xiàn) HTML5 拖放 API,處理 dragstart, dragover, 和 drop 事件,以便將元素從 source 移動(dòng)到 target

1. 創(chuàng)建示例 HTML 頁(yè)面 (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>

說(shuō)明:

  • draggable="true": 必須在可拖拽的元素上設(shè)置此屬性。
  • CSS: 設(shè)置了 position: absolute 以便在容器內(nèi)精確定位區(qū)塊。
  • JavaScript:
    • dragstart: 設(shè)置拖拽數(shù)據(jù)(可選),添加視覺(jué)反饋類。
    • dragend: 移除視覺(jué)反饋類。
    • dragover必須調(diào)用 event.preventDefault(),否則 drop 事件不會(huì)觸發(fā)。
    • drop必須調(diào)用 event.preventDefault()。然后執(zhí)行元素的移動(dòng)邏輯(removeChild + appendChild)。
    • 為了演示雙向拖拽,source-area 也監(jiān)聽了 dragover 和 drop。

2. Pytest + Playwright 測(cè)試代碼 (test_block_drag_drop.py)

首先,確保安裝了必要的庫(kù):

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.")

說(shuō)明:

  • Fixture page: 為每個(gè)測(cè)試函數(shù)提供一個(gè)新的瀏覽器頁(yè)面實(shí)例,并在測(cè)試結(jié)束后自動(dòng)關(guān)閉,確保測(cè)試隔離。
  • page.goto(): 導(dǎo)航到你的本地 HTML 文件。務(wù)必更新 file:///... 后面的路徑為你實(shí)際存放 drag_drop_block.html 的絕對(duì)路徑。
  • page.drag_and_drop(source, target): Playwright 提供的核心方法,用于模擬拖放操作。它會(huì)處理底層的鼠標(biāo)事件序列。
  • expect(...): Playwright 的斷言庫(kù),用于驗(yàn)證 DOM 狀態(tài)(元素是否存在、是否可見(jiàn)等)。它具有內(nèi)置的智能等待機(jī)制。

3. 運(yùn)行測(cè)試

在終端中,切換到包含 test_block_drag_drop.pydrag_drop_block.html 的目錄,然后運(yùn)行:

pytest test_block_drag_drop.py -v
  • -v 選項(xiàng)提供更詳細(xì)的輸出。

如果配置正確,你應(yīng)該會(huì)看到類似以下的輸出,并且瀏覽器窗口會(huì)短暫出現(xiàn)以執(zhí)行測(cè)試:

============================= 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 ===============================

這表明兩個(gè)測(cè)試(從 source 到 target,以及從 target 回到 source)都成功通過(guò)了。

以上就是使用pytest結(jié)合Playwright實(shí)現(xiàn)頁(yè)面元素在兩個(gè)區(qū)域間拖拽功能的詳細(xì)內(nèi)容,更多關(guān)于pytest Playwright頁(yè)面元素拖拽的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python數(shù)字圖像處理代數(shù)之加減乘運(yùn)算

    Python數(shù)字圖像處理代數(shù)之加減乘運(yùn)算

    這篇文章主要介紹了Python數(shù)字圖像處理代數(shù)運(yùn)算,對(duì)其中的加、減、乘運(yùn)算分別作了詳細(xì)的講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-09-09
  • python 寫一個(gè)性能測(cè)試工具(一)

    python 寫一個(gè)性能測(cè)試工具(一)

    這篇文章主要介紹了利用python 寫一個(gè)性能測(cè)試工具,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2020-10-10
  • Python數(shù)據(jù)分析之雙色球基于線性回歸算法預(yù)測(cè)下期中獎(jiǎng)結(jié)果示例

    Python數(shù)據(jù)分析之雙色球基于線性回歸算法預(yù)測(cè)下期中獎(jiǎng)結(jié)果示例

    這篇文章主要介紹了Python數(shù)據(jù)分析之雙色球基于線性回歸算法預(yù)測(cè)下期中獎(jiǎng)結(jié)果,涉及Python基于線性回歸算法的數(shù)值運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下
    2018-02-02
  • Flask框架利用Echarts實(shí)現(xiàn)繪制圖形

    Flask框架利用Echarts實(shí)現(xiàn)繪制圖形

    echarts是百度推出的一款開源的基于JavaScript的可視化圖表庫(kù),該開發(fā)庫(kù)目前發(fā)展非常不錯(cuò),且支持各類圖形的繪制可定制程度高。如下演示案例中,將分別展示運(yùn)用該繪圖庫(kù)如何前后端交互繪制(餅狀圖,柱狀圖,折線圖)這三種最基本的圖形,需要的可以參考一下
    2022-10-10
  • Python入門教程3. 列表基本操作【定義、運(yùn)算、常用函數(shù)】

    Python入門教程3. 列表基本操作【定義、運(yùn)算、常用函數(shù)】

    這篇文章主要介紹了Python列表基本操作,結(jié)合實(shí)例形式總結(jié)分析了Python針對(duì)列表的基本定義、判斷、運(yùn)算及各種常用函數(shù)與相關(guān)使用技巧,需要的朋友可以參考下
    2018-10-10
  • Python爬蟲基礎(chǔ)之requestes模塊

    Python爬蟲基礎(chǔ)之requestes模塊

    這篇文章主要介紹了Python爬蟲基礎(chǔ)之requestes模塊,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)python爬蟲的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Python在Excel工作表添加數(shù)據(jù)驗(yàn)證的示例代碼

    Python在Excel工作表添加數(shù)據(jù)驗(yàn)證的示例代碼

    在處理電子表格數(shù)據(jù)時(shí),確保輸入數(shù)據(jù)的準(zhǔn)確性和一致性至關(guān)重要,本文將介紹如何使用 Python 在 Excel 工作表中添加各種類型的數(shù)據(jù)驗(yàn)證規(guī)則,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下
    2026-05-05
  • Python上下文管理器Content Manager

    Python上下文管理器Content Manager

    在Python中,我們會(huì)經(jīng)常聽到上下文管理器,那么上下文管理器到底是干什么的,本文就來(lái)介紹一下,感興趣的小伙伴們可以參考一下
    2021-06-06
  • 詳解Python手寫數(shù)字識(shí)別模型的構(gòu)建與使用

    詳解Python手寫數(shù)字識(shí)別模型的構(gòu)建與使用

    這篇文章主要為大家詳細(xì)介紹了Python中手寫數(shù)字識(shí)別模型的構(gòu)建與使用,文中的示例代碼簡(jiǎn)潔易懂,對(duì)我們學(xué)習(xí)Python有一定的幫助,需要的可以參考一下
    2022-12-12
  • Pygame實(shí)戰(zhàn)練習(xí)之炸彈人學(xué)院游戲

    Pygame實(shí)戰(zhàn)練習(xí)之炸彈人學(xué)院游戲

    炸彈人學(xué)院想必是很多人童年時(shí)期的經(jīng)典游戲,我們依舊能記得抱個(gè)老人機(jī)娛樂(lè)的場(chǎng)景,下面這篇文章主要給大家介紹了關(guān)于如何利用python寫一個(gè)簡(jiǎn)單的炸彈人學(xué)院小游戲的相關(guān)資料,需要的朋友可以參考下
    2021-09-09

最新評(píng)論

濉溪县| 垣曲县| 石棉县| 登封市| 法库县| 海门市| 望江县| 金坛市| 深州市| 永年县| 永登县| 绥阳县| 上饶市| 德惠市| 玉屏| 府谷县| 洛隆县| 丰都县| 苍山县| 邻水| 山东省| 师宗县| 永丰县| 天津市| 那坡县| 堆龙德庆县| 抚远县| 那曲县| 东港市| 美姑县| 长岭县| 耒阳市| 蒙山县| 普宁市| 台中市| 嫩江县| 武隆县| 繁峙县| 灵川县| 喀喇沁旗| 三穗县|