【问题标题】:How to fetch copied to clipboard content in cypress如何在柏树中获取复制到剪贴板的内容
【发布时间】:2020-05-07 05:46:44
【问题描述】:

如何在 cypress 中获取“剪贴板”内容。我的 Web 应用程序中有一个按钮,单击按钮系统将执行“复制到剪贴板”并显示一条消息。下面是复制到剪贴板的 url 内容示例(此 url 内容与网站 url 不同

https://someurl.net/machines/0c459829-a5b1-4d4b-b3c3-18b03c1c969a/attachments/a30ceca7-198e-4d87-a550-04c97fbb9231/download

我仔细检查了那个按钮标签中没有href 属性。所以我使用了一个名为 clipboardy 的插件,并添加了plugins/index.js 文件

 const clipboardy = require('clipboardy');
    module.exports = ( on ) => {
        on('task', {
            getClipboard () {
                return clipboardy.readSync();
            }
        });
    };

在我的测试中,我使用 cy.task() 来获取剪贴板内容,但这并没有打印实际的 url 内容

cy.get('td').find('div').find('span').find('button').find('i').eq(0).click().then(()=>{
          cy.task('getClipboard').then((data)=>{
          console.log("Helloooo:"+data);
      })
    })

<td class="sc-hgRTRy duUdhJ">
<div>
<span class="sc-bYwvMP jTmLTC">
<span class="sc-jzJRlG iVpVVy">
<span role="button" aria-expanded="true" aria-haspopup="true" aria-owns="5aa03785-1370-455e-a838-4154f7481a7b">
<button class="sc-feJyhm cJOKrG">
<i class="icon fas fa-link sc-htpNat cQABgO" aria-hidden="true" data-component-type="icon">
</i>
</button>
</span>
</span>
</span>
</div>
</td>

【问题讨论】:

  • 我也试过getClipboard () { return clipboardy.read(); }
  • @MakwanaPrahlad 给出的测试(使用输入)有效,这表明您的按钮 .click() 没有触发事件。这可能是“本地事件”问题,但也有可能点击不在正确的元素上。你能显示有td的部分html吗?
  • 了解运行测试时是否出现“复制到剪贴板”消息也会很有帮助。
  • 是的,它在运行文本时显示消息。我完全同意@MakwanaPrahlad 测试,但我的情况不同
  • 我不明白,你能把它贴在问题上吗?通常.then()的参数是一个jquery对象,所以你可能不能"Hello:" + data,而可能是"Hello:" + data[0]

标签: javascript cypress


【解决方案1】:

可以解决访问剪贴板的问题,但主要问题是 document.execCommand('copy') 不起作用(如上所述),我认为这是您的应用程序的主要(也是唯一?)方式以编程方式将文本放入用户的剪贴板。

假设它以某种方式发生(或在上游固定),可以检查剪贴板的内容,例如通过使用剪贴板:

npm i -D clipboardy

插件/index.js:

const clipboardy = require('clipboardy');
module.exports = ( on ) => {
    on('task', {
        getClipboard () {
            return clipboardy.readSync();
        }
    });
};

在您的规范中:

describe('test', () => {
    it('test', () => {
        cy.document().then( doc => {
            doc.body.innerHTML = '<input id="inp">';
        });
        cy.get('#inp').type('test{selectall}');
        cy.document().then( doc => {
            doc.execCommand('copy');
        });
        cy.task('getClipboard').should('contain', 'test');
    });
});

我希望这段代码对你有用。 谢谢。

【讨论】:

  • 谢谢,我之前看到过相同的方法,在您的示例中,您有一个输入字段,在该输入字段中输入一些文本,然后断言该文本内容。我的要求不同,我的网络应用程序中没有输入字段,我只有一个按钮,当我点击上面的按钮时,一些文本内容被复制到剪贴板,然后我会弹出一条消息“复制到剪贴板",我需要获取剪贴板内容(请参阅上面的问题)。我需要获取该 URL 以进一步处理其他业务案例。
  • 我已经检查并发现该按钮中没有href 属性(如上面有问题的屏幕截图所示)
  • 我也试过下面的,但它只是打印代码,cy.get('td').find('div').find('span').find('button').find('i').eq(0).click().task('getClipboard').then((data)=&gt;{ console.log("Helloooo:"+data); })
  • github 上剪贴板的自述页面说 readSync() 在浏览器中不起作用。我还看到导致 cypress 测试运行挂起的间歇性问题。其他人没有看到这些问题吗?
【解决方案2】:

如果你不想使用clipboardy package,你也可以使用这个:

cy.window().then((win) => {
    win.navigator.clipboard.readText().then((text) => {
      expect(text).to.eq('your copied text');
    });
  });

在你的情况下,它变成了类似

   cy.get('td').find('div').find('span').find('button').find('i').eq(0).click().then(()=>{
    cy.window().then((win) => {
      win.navigator.clipboard.readText().then((text) => {
        console.log("Helloooo:"+text);
      });
    });
   })

【讨论】:

  • 我不断收到异常“文档未聚焦”
  • 确保您没有点击其他窗口或其他东西。我遇到了同样的错误,实际上只是被测试的浏览器必须是活动窗口。
  • 您使用什么语法来检查 then() 中的文本值?期望()什么?
【解决方案3】:

我在 Gleb Bahmutov 的视频 Access the clipboard from Cypress test using Electron browser 中找到了这个测试剪贴板内容的好方法和简单的解决方案。

cy.window().its('navigator.clipboard')
  .invoke('readText').should('equal', 'copied text')

它使用新的Clipboard API(Chrome、FF 和 Opera:2018;Safari 和 Edge:2020;IE:否)

在视频中,Gleb 还建议使用 document.execCommand('copy') 的旧(已弃用)方法测试不支持剪贴板 API 的浏览器的案例。

它希望页面有一个输入字段或文本区域来粘贴内容。假设它是textarea#paste-here

// delete navigator.clipboard to force the app to use execCommand
cy.visit('index.html', {
  onBeforeLoad(window) {
    delete window.navigator.__proto__.clipboard
  }
})
cy.document().then(document => cy.spy(document, 'execCommand').as('exec'))

/* trigger the copy action here... cy.get(...).click() */

cy.get('@exec').should('have.been.calledOnceWith', 'copy')

cy.get('#paste-here').focus()
cy.document().invoke('execCommand', 'paste')

cy.get('#paste-here').should('have.value', 'copied text')

由于剪贴板权限对话框,此测试只能在 Electron 浏览器中进行自动化 (CI)。要使其在 Chrome 中运行,请观看另一个 Gleb 的视频Give Chrome Browser Clipboard Permissions from Cypress Test。否则,您可以使用 Test configuration object 将测试限制为仅在 Electron 中运行:

describe('Clipboard', {browser: 'electron'}, () => {
...

【讨论】:

  • 有趣的是,当设置电子时,我的规格“由于浏览器而被跳过”
  • 另外,cy.window().its('navigator.clipboard') .invoke('readText').should('equal', 'copyed text') 抛出“TypeError”:无法设置[object DOMException] 的属性消息现在突然只有一个 getter ..
【解决方案4】:

我设法通过在单击按钮后打印出产生的值来获取复制的链接,然后在控制台中搜索对象以找到链接。我在[object]._vClipboard.clipboardAction.text 中找到了链接,如下所示:

cy.get('[data-test=copy-link-button]').click().then(($clipboard) => {
   const copiedLink = $clipboard[0]._vClipboard.clipboardAction.text;
   cy.visit(copiedLink);
});

我希望这会有所帮助。

【讨论】:

  • 你是如何打印出产值的?我的按钮有“复制文本”的文本,所以我不能抓取它自己的文本,我需要抓取它在剪贴板中放置的内容。所以,我想知道单击按钮后如何打印产生的值?
  • @SaintAvalon,您可以这样做:cy.get('[data-test=copy-link-button]').click().then(($value) =&gt; { console.log($value); }); 这将在单击按钮后将生成的值打印到控制台。然后您可以在控制台中看到打印出的对象中的剪贴板文本:$value[0]._vClipboard.clipboardAction.text。确保将 [data-test=copy-link-button] 替换为相应按钮的数据测试
【解决方案5】:

阅读这篇文章确实帮助我解决了我自己的问题,我不得不使用 OP 和第一条评论的混合物。这对我有用:

     cy.get(':nth-child(2) > .mat-card > .row > .col-sm-3 > .mat-focus-indicator').click().then(() => {
        cy.task('getClipboard').then(($clip) => {
             const url = $clip;
             cy.log('this is what was in clipboard', url);
             cy.visit(url);
         });
     });

这从我单击的按钮中给了我想要的 URL。然后我只是将它传递给 cy.visit 以访问我刚刚复制的 url。效果很好。

【讨论】:

    【解决方案6】:

    https://stackoverflow.com/a/61653634/2742007 处的代码应该适合调用浏览器支持的 clipboardy 函数,正如“opike”所评论的那样:注意asyncread() 而不是readSync()

    const clipboardy = require('clipboardy');
    module.exports = (on, config) => {
      on('task', {
        async getClipboard() {
          return clipboardy.read();
        }
      });
    }
    

    【讨论】:

      【解决方案7】:

      注意:以上使用 window.navigator https://stackoverflow.com/a/68871590/5667941 ,仅适用于 Electron。对于 Chrome,需要用户许可

      【讨论】:

        【解决方案8】:

        尝试使用cy.window(),您可以照常使用navigator.clipboard 进行粘贴和复制。

        it("Paste cliboard numbers", () => {
          cy.window()
            .then((win) => {
              return win.navigator.clipboard.writeText("234");
            `})`
            .then(() => {
              cy.get("[data-test=paste]").click();
              cy.get("[data-test=calc-input]").should("have.text", 234);
            });
        });
        

        【讨论】:

          【解决方案9】:

          到目前为止,没有其他答案对我有用 cypress ui,但我设法通过直接使用 Cypress.Promises 和 window.navigator 找到了一个没有任何额外库或插件的解决方案......这里是:

          cy.window().then(win =>
            new Cypress.Promise((resolve, reject) =>
              win.navigator
                .clipboard
                .readText()
                .then(resolve)
                .catch(reject))
          ).should('eq', '`myExpectedClipboardValue')
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-12-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-05-18
            • 2011-05-13
            相关资源
            最近更新 更多