首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在宁静js中执行拖放操作。

在宁静js中执行拖放操作。
EN

Stack Overflow用户
提问于 2017-10-17 11:56:31
回答 1查看 1.3K关注 0票数 1

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

更新:

我实现了Jan的HTML5解决方案,但是我得到了以下错误消息:

这就是我的任务实现:

代码语言:javascript
复制
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) {
 }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-18 23:41:55

目前还没有内置的相互作用,但是Serenity/JS很容易扩展,所以您可以创建一个自定义交互(甚至可以将它作为拉请求提交?)。

下面是创建自定义交互的步骤。

1.量角器方法的研究

首先,考虑一下如何使用普通的Protractor实现这个功能?

量角器API文档建议以下选项:

代码语言:javascript
复制
// 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风格的交互,基于Protractor文档中的第二个示例:

代码语言:javascript
复制
browser.actions().
    dragAndDrop(element1, element2).
    perform();

提供以下接口:

代码语言:javascript
复制
actor.attemptsTo(
    DragAndDrop(element1).onto(element2);
)

这意味着我可以将交互的DSL定义为:

代码语言:javascript
复制
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.界定相互作用

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

代码语言:javascript
复制
import { Interaction } from 'serenity-js/lib/screenplay-protractor';

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

宁静/JS为BrowseTheWeb提供了一个"能力“。这种能力是围绕剧本模式对象的-style包装器,这意味着您可以使用它访问特定于量角器的API。

所以如果你已经给了你的演员BrowseTheWeb的能力

代码语言:javascript
复制
import { Actor, BrowseTheWeb } from 'serenity-js/lib/screenplay-protractor';

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

您可以在interaction body中访问它。

代码语言:javascript
复制
Interaction.where(`#actor drags ${draggable} onto ${dropzone}`, actor => {
    return BrowseTheWeb.as(actor).actions().
        dragAndDrop(..., ...).
        perform();
});

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

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

代码语言:javascript
复制
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.把它们放在一起

鉴于以上所述,由此产生的实现如下:

代码语言:javascript
复制
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拖放铬

请注意,除非HTML5拖放修复了这一缺陷,否则上述实现在Chromedriver中可能无法工作。

或者,您可以安装html-dnd模块并按如下方式实现Screenplay样式的任务(您需要Serenity/JS1.9.3或更高版本):

代码语言:javascript
复制
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),
    ),
});

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

1月

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46789562

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档