在serenity-js中执行拖放操作

时间:2017-10-17 11:56:31

标签: drag-and-drop serenity-js

我正在寻找一种使用serenity-js(http://serenity-js.org/)执行拖放的方法,但我找不到任何示例。我可以找到的是量角器方式,但因为量角器是在serenity-js框架中出现的,所以我想知道如何使这个工作。 (对不起,我是TS和javascript的新手)

UPDATE:

我实现了Jan Molak的HTML5解决方法但是我收到以下错误消息: enter image description here

这是我的任务实施:

import { Execute, Target } from 'serenity-js/lib/screenplay-protractor';

import { PerformsTasks, Task } from 'serenity-js/lib/screenplay';

const dragAndDropScript = require('html-dnd').code; // tslint:disable-
line:no-var-requires

 export class DragAndDrop implements Task {

 static with(draggable: Target, dropzone: Target) {
    return new DragAndDrop(draggable, dropzone);
 }

 performAs(actor: PerformsTasks): PromiseLike<void> {
    return actor.attemptsTo(
        Execute.script(dragAndDropScript).withArguments(this.draggable, 
 this.dropzone)
    );
 }

 constructor(private draggable: Target, private dropzone: Target) {
 }
}

1 个答案:

答案 0 :(得分:1)

目前尚未内置interaction,但Serenity / JS很容易扩展,因此您可以创建自定义交互(甚至可以将其作为{{3提交) }}?)。

以下是我创建自定义互动所需的步骤。

1。研究量角器方式

首先,考虑如何使用普通的Protractor实现此功能?

pull request建议使用以下选项:

// Dragging one element to another.
browser.actions().
    mouseDown(element1).
    mouseMove(element2).
    mouseUp().
    perform();

// You can also use the `dragAndDrop` convenience action.
browser.actions().
    dragAndDrop(element1, element2).
    perform();

// Instead of specifying an element as the target, you can specify an offset
// in pixels. This example double-clicks slightly to the right of an element.
browser.actions().
    mouseMove(element).
    mouseMove({x: 50, y: 0}).
    doubleClick().
    perform();

正如您所看到的,上述所有示例都依赖于browser.actions() API,因此我们需要找到一种方法来掌握它。

但在潜水之前,让我们尝试从外向内设计我们的新互动,并考虑我们想要的界面。

2。定义您想要使用的DSL

假设我想根据量角器文档中的第二个示例进行Serenity / JS,Screenplay风格的交互:

browser.actions().
    dragAndDrop(element1, element2).
    perform();

提供以下界面:

actor.attemptsTo(
    DragAndDrop(element1).onto(element2);
)

这意味着我可以按如下方式定义我的互动DSL:

import { Target } from 'serenity-js/lib/screenplay-protractor';

export const DragAndDrop = (draggable: Target) => ({
    onto: (dropzone: Target) => ...
})

这将为我提供我想要的DragAndDrop(draggable).onto(dropzone)语法。

下一步是DragAndDrop(draggable).onto(dropzone)调用返回实际的互动。

3。定义交互

您可以使用以下简写语法定义交互:

import { Interaction } from 'serenity-js/lib/screenplay-protractor';

Interaction.where(`#actor drags ${draggable} onto ${dropzone}`, actor => {
    // interaction body
});

Serenity / JS提供了一个&#34; Protractor's API documentation&#34;到ability。 此功能是protractor对象的BrowseTheWeb样式包装器,这意味着您可以使用它来访问特定于量角器的API。

所以,只要你已经让你的演员能够BrowseTheWeb

import { Actor, BrowseTheWeb } from 'serenity-js/lib/screenplay-protractor';

const Alice = Actor.named('Alice').whoCan(BrowseTheWeb.using(protractor.browser));

您可以在interaction body

中访问它
Interaction.where(`#actor drags ${draggable} onto ${dropzone}`, actor => {
    return BrowseTheWeb.as(actor).actions().
        dragAndDrop(..., ...).
        perform();
});

另一个缺失的步骤是,量角器的browser.actions.dragAndDrop(..., ...)方法希望您提供WebElement的实例,而不是Serenity / JS特定的Target

这意味着我们需要在传递之前解析Target

Interaction.where(`#actor drags ${draggable} onto ${dropzone}`, actor => {

    const browse           = BrowseTheWeb.as(actor),
          draggableElement = browse.locate(draggable),
          dropzoneElement  = browse.locate(dropzone);

    return browse.actions().
        dragAndDrop(draggableElement, dropzoneElement).
        perform();
});

4。全部放在一起

鉴于上述所有情况,最终的实现可能如下所示:

import { Actor, BrowseTheWeb, Interaction, Target } from 'serenity-js/lib/screenplay-protractor';

export const DragAndDrop = (draggable: Target) => ({
    onto: (dropzone: Target) => Interaction.where(
        `#actor drags ${draggable} onto ${dropzone}`,
        actor => {
            const browse           = BrowseTheWeb.as(actor),
                  draggableElement = browse.locate(draggable),
                  dropzoneElement  = browse.locate(dropzone);

            return browse.actions().
                dragAndDrop(draggableElement, dropzoneElement).
                perform();
    })
})

HTML5拖放和Chrome

请注意,除非Screenplay Pattern已修复,否则上述实施可能无法在HTML5 drag and drop的Chromedriver中使用。

或者,您可以安装this defect模块并按如下方式实现编剧风格的任务(您需要Serenity / JS 1.9.3或更高版本):

import { Execute, Target, Task } from 'serenity-js/lib/screenplay-protractor';

const dragAndDropScript = require('html-dnd').code; // tslint:disable-line:no-var-requires

export const DragAndDrop = (draggable: Target) => ({
    onto: (dropzone: Target) => Task.where(`#actor drags ${draggable} onto ${dropzone}`,
        Execute.script(dragAndDropScript).withArguments(draggable, dropzone),
    ),
});

希望这有助于并感谢您加入Serenity / JS社区: - )