【问题标题】:Emulating a clipboard copy/paste with Selinum + Capybara使用 Selinum + Capybara 模拟剪贴板复制/粘贴
【发布时间】:2019-09-20 19:23:45
【问题描述】:

我的前端 UI 中有一个“复制链接”按钮。单击时,输入框内的 URL 会使用此 JS 复制到用户的剪贴板:

const copyTextarea = document.querySelector("#copy-link-button");
copyTextarea.focus();
copyTextarea.select();
document.execCommand('copy');

当我在本地试用时,此功能完美运行,因此我知道该功能本身运行正常。

但是,我无法使用 Capybara 测试副本。我从this post 知道 Capybara 不提供剪贴板 API,但我的解决方法是 -

  1. 使用“复制链接”按钮复制链接
  2. 导航到其他一些输入/文本字段
  3. 使用 CTRL+V 粘贴到字段中并读取字段内容进行验证

我的测试:

# Copy the link
page.find("#copy-link-button").click
wait_for_ajax

# Visit some other page that I know has an input/text field
visit account_settings_path

input = page.find("#user_email")

# Clear the field
fill_in("user[email]", with: "")

# Paste in the contents of the clipboard
input.base.send_keys([:control, "v"])

# Validate
expect(input.value).to eq("some value");

但是没有任何内容粘贴到该输入中(input.value 和 input.text 返回 "")。

这是一种有效的方法吗?首先是复制文本的问题还是我在粘贴数据时出错了?

谢谢!

【问题讨论】:

    标签: selenium rspec capybara


    【解决方案1】:

    注意:由于此 Chrome 的原始发布已经更改了可用的权限类型。对于无头解决方案,请转到 https://chromedevtools.github.io/devtools-protocol/tot/Browser/#type-PermissionType 以查看当前可用的权限类型


    有很多关于访问剪贴板内容的安全规则,所以尝试从 Capybara 进行粘贴工作真的会让人感到沮丧。此外,当 ctrl/command v 作为击键发送时,大多数浏览器实际上不会做任何事情,因为它是系统触发的操作,而不是浏览器。

    但是,由于您只是想验证复制是否有效,实际上并不需要触发粘贴,因此您只需要绕过权限要求即可使用剪贴板 API。如果您使用的是 Chrome(在非无头配置中 - 目前无法无头工作),您可以通过在驱动程序注册中设置 profile.content_settings.exceptions.clipboard 首选项来做到这一点

    Capybara.register_driver :chrome do |app|
      options = Selenium::WebDriver::Chrome::Options.new
      options.add_preference('profile.content_settings.exceptions.clipboard', {
        '*': {'setting': 1}
      })
      Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
    end
    

    如果您在无头模式下运行并在 Chrome 中使用最新的 Capybara 和 selenium,则另一种选择是使用 CDP 授予权限

    page.driver.browser.execute_cdp('Browser.grantPermissions', origin: page.server_url, permissions: ['clipboardRead', 'clipboardWrite'])
    

    获得权限后,您就可以使用evaluate_async_script 访问剪贴板数据

    clip_text = page.evaluate_async_script('navigator.clipboard.readText().then(arguments[0])')
    

    注意事项:

    1. 在元素上调用send_keys不需要使用base,直接在元素上调用即可
    2. expect(input.value).to eq("some value") 会导致不稳定的测试,您应该使用 Capybara 提供的匹配器,例如 expect(page).to have_field(with: 'some value') 或 expect(input).to match_selector(:field, with: 'some value')

    【讨论】:

    • 这个真的很有用,谢谢!我正在运行 headless chrome,所以会尝试后者
    • 谢谢!与常规 chrome 驱动程序一起工作得很好;然而,截至 2020 年 9 月,headless chrome 正在向我抛出这个:invalid argument: Unknown permission type: clipboardRead (Session info: headless chrome=84.0.4147.125)
    • @danielricecodes 这就是使用前沿功能的问题——它已经改变了。您可以在 chromedevtools.github.io/devtools-protocol/tot/Browser/… 查看当前支持的权限类型 - 您可能想要“clipboardReadWrite”
    • 感谢您的快速回复!当我看到你的评论时,我刚回来编辑我的评论!是的,权限确实合并了。只需使用clipboardReadWrite 就可以完美地工作!
    • 解决方案在 2021 年运行良好! @danielricecodes 提到了一些细微的变化
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-24
    • 1970-01-01
    相关资源
    最近更新 更多