英文:
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("**/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},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
<script>
fetch('https://some-domain/api/MIDI/1.mid')
</script>
Test
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')
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('**/MIDI/*', (req) => {
const fixtureName = req.url.split('/').pop()
req.reply( {
headers: {
'content-type': "audio/sp-midi"
},
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(<fixturefile>, 'binary')
, 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论