如何在赛普拉斯中用夹具模拟图像

How to mock an image with a fixture in cypress

我正在使用 cypress 来测试我的 VueJS 应用程序。我遇到的一件事是模拟要在页面上显示的图像。对于我的用例,我只是使用以下代码加载用户配置文件:

describe('Test Login', () => {
  it('Can Login', () => {
    cy.server();
    cy.route({
      method: 'GET',
      url: '/api/account/',
      response: 'fx:profile.json',
    });
    cy.route('**/media/demo1.png', 'fx:demo1.png');
  });
});

fixtures/profile.json

{
    "avatar": "http://localhost:8080/media/demo1.png",
    "username": "cypress",
    "email": "email@cypress.io",
    "pk": 1,
    "is_staff": true,
    "is_superuser": true,
    "is_active": true
}

配置文件夹具数据在测试中正确加载。在我的 fixtures 文件夹中,我还有一个 demo1.png 文件。我希望在我的测试期间加载此图像并显示在页面上,但它显示为损坏的图像。

在网络选项卡中,它显示 demo1.png 为损坏的图像,响应代码为 200,类型为 text/html

cypress 文档主要在上传图像的上下文中讨论图像,但我无法找到如何模拟通过 <img> 标记加载的图像的示例。有更简单的方法吗?

不知道这个回答能不能帮到你。但至少它是解决这个问题的方法 ;-)

假设我们有这样一个 HTML:

<html>
    <body>
        <button id="button">load</button>
        <div id="profile">

        </div>

        <script>
            function httpGetAsync(theUrl, callback)
            {
                var xmlHttp = new XMLHttpRequest();
                xmlHttp.onreadystatechange = function() { 
                    if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
                        callback(JSON.parse(xmlHttp.responseText));
                }
                xmlHttp.open("GET", theUrl, true); // true for asynchronous 
                xmlHttp.send(null);
            }

            document.getElementById("button").addEventListener("click", () => {

                httpGetAsync("/api/account/", (result) => {
                    var div = document.querySelector("#profile");
                    var img = document.createElement("img");
                    img.src = result.avatar;
                    div.appendChild(img)
                })
            })

        </script>
    </body>
</html>

来源:

并且您想在点击完成后加载配置文件。然后你可以使用 MutationObserver 来替换 img.src.

首先,编写MutationObserver:

var observeDOM = (function(){
    var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

    return function( obj, callback ){
      if( !obj || !obj.nodeType === 1 ) return; // validation

      if( MutationObserver ){
        // define a new observer
        var obs = new MutationObserver(function(mutations, observer){
            callback(mutations);
        })
        // have the observer observe foo for changes in children
        obs.observe( obj, { childList:true, subtree:true });
      }

      else if( window.addEventListener ){
        obj.addEventListener('DOMNodeInserted', callback, false);
        obj.addEventListener('DOMNodeRemoved', callback, false);
      }
    }
  })();

(大量复制粘贴自 Detect changes in the DOM

现在您可以这样做了:

describe('Test Login', () => {
    it('Can Login', () => {
        var win = null;
      cy.server();
      cy.route({
        method: 'GET',
        url: '/api/account/',
        response: 'fx:profile.json'
      });
      cy.visit("index.html").then(w => { 
          cy.get("#profile").then(pro => {
              var e = pro[0];
              observeDOM(e, (m) => {
                // add a red dot image
                m[0].addedNodes[0].src = "data:image/png;base64,"+
                "iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGP"+
                "C/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IA"+
                "AAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1J"+
                "REFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jq"+
                "ch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0"+
                "vr4MkhoXe0rZigAAAABJRU5ErkJggg=="
            })
          })
          cy.get("button").click()
      })
    });
  });

(是的,至少有几行代码是我自己写的;-P)

您可以从 fixtures 文件夹的 img.src 属性中读取图像。为了简单起见,我在这里使用了静态 base64 字符串。

结果:

我们的 aurelia 应用程序中没有使用这种东西,但我前段时间在一个私人项目中尝试过类似的东西。