无法在Cypress回复拦截中设置夹具的文件类型

huangapple go评论54阅读模式
英文:

Cannot set file type of fixtures in Cypress reply intercepts

问题

我在尝试在 Cypress 拦截中设置一个 Midi 文件的桩数据。我正在从 URL 中派生一个夹具(fixture)来加载并在响应中使用。我大致做了这样的操作:

cy.intercept("**/MIDI/*", (req) => {
const fixtureName = get_last_part_of(req.url) // 这将生成一个像 1.mid 的夹具
req.reply( {
headers: {
'content-type': "audio/sp-midi"
},
fixture: "midi/" + fixtureName
})

当我加载这个文件时,在浏览器日志中出现了关于无效 MIDI 文件的错误:

ERROR Error: Uncaught (in promise): Bad MIDI file. Expected 'MTrk', got: 'MTr'
at resolvePromise (polyfills.js:8576:21)
at polyfills.js:8485:11


我 *认为* 这是因为 `1.mid` 被视为 `utf-8`,但我希望它被视为 `binary`。在 `reply` 中是否有指定这一点的方法?

我已经尝试在拦截中直接读取文件,但由于我使用了 cy.visit 调用拦截,所以出现了错误。
英文:

I'm trying to stub a midi file in a Cypress intercept. From the URL I am deriving a fixture to load and use in the reply. I am doing something like:

cy.intercept("**/MIDI/*", (req) => {
  const fixtureName = get_last_part_of(req.url)  // This will yield a fixture like 1.mid
  req.reply( {
    headers: {
      'content-type': "audio/sp-midi"
    },
    fixture: "midi/" + fixtureName
  })

When I load this file I get an error in the browser logs about an invalid MIDI file:

ERROR Error: Uncaught (in promise): Bad MIDI file.  Expected 'MTrk', got: 'MTr'
    at resolvePromise (polyfills.js:8576:21)
    at polyfills.js:8485:11

I think this is because the 1.mid is treated as utf-8, but I want it to be treated as binary. Is there a way to specify this in the reply?

I've tried reading the file directly in the intercept but because I am using cy.visit that invokes the intercept, I am getting an error.

答案1

得分: 2

这里有一些线索 Fixture - Default Encoding。 "已知扩展名" 列表不包括 mid,下面的段落确认默认应该是 utf8

从这里开始 Intercept - StaticResponse objects

将 fixture 作为 HTTP 响应体提供(在省略 body 时允许)。使用与文件类型默认不同的编码读取内容,传递 fixture 如 path,encoding

这可能会起作用:

cy.intercept("**/MIDI/*", (req) => {
  const fixtureName = get_last_part_of(req.url)  // 这将产生一个如 1.mid 的 fixture
  req.reply( {
    headers: {
      'content-type': "audio/sp-midi"
    },
    fixture:  `midi/${fixtureName},binary`
  })

使用样本 midi

这是使用非常简单的测试页面的通过测试,遵循问题中给出的信息。

示例页面

<script>
  fetch('https://some-domain/api/MIDI/1.mid')
</script>

测试

cy.intercept('**/MIDI/*', (req) => {
  const fixtureName = req.url.split('/').pop()
  req.reply( {
    headers: {
      'content-type': "audio/sp-midi"
    },
    fixture:  `midi/${fixtureName},binary`
  })
}).as('midi')

cy.visit('midi.html')

cy.wait('@midi')
英文:

There are some clues here Fixture - Default Encoding. The "known extensions" list doesn't include mid, and the following paragraph confirms that the default would be utf8.

From here Intercept - StaticResponse objects

> Serve a fixture as the HTTP response body (allowed when body is omitted). Read the contents with an encoding other than the default for the file type, pass the fixture like path,encoding.

This might work:

cy.intercept(&quot;**/MIDI/*&quot;, (req) =&gt; {
  const fixtureName = get_last_part_of(req.url)  // This will yield a fixture like 1.mid
  req.reply( {
    headers: {
      &#39;content-type&#39;: &quot;audio/sp-midi&quot;
    },
    fixture:  `midi/${fixtureName},binary`
  })

Using a sample midi

Here's a passing test using a very simple test page, following the information given in the question.

Sample page

&lt;script&gt;
  fetch(&#39;https://some-domain/api/MIDI/1.mid&#39;)
&lt;/script&gt;

Test

cy.intercept(&#39;**/MIDI/*&#39;, (req) =&gt; {
  const fixtureName = req.url.split(&#39;/&#39;).pop()
  req.reply( {
    headers: {
      &#39;content-type&#39;: &quot;audio/sp-midi&quot;
    },
    fixture:  `midi/${fixtureName},binary`
  })
}).as(&#39;midi&#39;)

cy.visit(&#39;midi.html&#39;)

cy.wait(&#39;@midi&#39;)

No error occurs, which makes me think you are looking in the wrong place.

答案2

得分: 0

现在我对这个问题有了答案,虽然我不完全理解发生了什么。我不再使用binary编码,而是使用null。所以,如果我这样做:

cy.intercept('**/MIDI/*', (req) => {
  const fixtureName = req.url.split('/').pop()
  req.reply( {
    headers: {
      'content-type': "audio/sp-midi"
    },
    fixture:  `midi/${fixtureName},null`
  })
})

我不再收到MIDI错误。

我发现这一点的方法是将资源作为应用程序中的资产复制,然后让拦截请求从那里请求MIDI文件。我注意到请求体的长度是191。然后,我比较了从拦截的fixture加载的响应,并注意到它是220。当我使用cy.readFile(<fixturefile>, 'binary')的结果检查长度时,发生了相同的情况,直到我设置了null编码。这创建了一个在消息体中使用的缓冲区,而不是它的“binary”表示。

英文:

I now have an answer to this, though I don't completely understand what is happening. Instead of using the binary encoding, I have to use null. So, if I do

cy.intercept(&#39;**/MIDI/*&#39;, (req) =&gt; {
  const fixtureName = req.url.split(&#39;/&#39;).pop()
  req.reply( {
    headers: {
      &#39;content-type&#39;: &quot;audio/sp-midi&quot;
    },
    fixture:  `midi/${fixtureName},null`
  })
})

I no longer get the MIDI error.

The way that I discovered this was to copy the resource as an asset in the app I was testing, and have the intercept request the MIDI file from there. I noticed that the length of the body was 191. Then, I compared the response loaded from the intercepted fixture, and noticed that it was 220. The same thing was happening when I checked the length using the result of cy.readFile(&lt;fixturefile&gt;, &#39;binary&#39;), until I set null encoding. This creates a buffer that is used in the body of the message, rather than a "binary" representation of it.

huangapple
  • 本文由 发表于 2023年4月7日 04:51:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75953672.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定