[英]How to return Map object from Cypress each?
So, I write TAF to automate user cases using Cypress.所以,我编写了 TAF 来使用 Cypress 自动化用户案例。 I'm a novice in it.
我是新手。
I need to return from Cypress each
command a Map
with some values to use it in next command as input value.我需要从 Cypress 返回
each
命令一个带有一些值的Map
以在下一个命令中将其用作输入值。
In DOM there are some amount of canvas
tags like this:在 DOM 中有一些像这样的
canvas
标签:
<canvas class="leaflet-tile leaflet-tile-loaded" width="256" height="256" style="width: 256px; height: 256px; transform: translate3d(613px, 246px, 0px); opacity: 1;"></canvas>
From style
attribute I need to extract two coordinates, so, just transform value:从
style
属性我需要提取两个坐标,所以,只需转换值:
width: 256px; height: 256px; transform: translate3d(613px, 246px, 0px); opacity: 1;
to到
613 246
and set it like a key to Map object.并将其设置为 Map 对象的键。 And as value I need to set a buffer of encoded canvas data.
作为值,我需要设置一个编码画布数据的缓冲区。
So, I add custom command like this:所以,我添加了这样的自定义命令:
function convertCanvasMatrixToPictureCommand() {
Cypress.Commands.add('renderCanvasMatrixToPng', { prevSubject: true }, (subject, savePath) => {
const bufferMap = new Map();
cy.wrap(subject)
.each(canvas => {
Cypress.Blob.canvasToBlob(canvas.get(0))
.then(blob => Cypress.Blob.blobToArrayBuffer(blob))
.then(buff => {
const coordinates = extract(canvas.attr('style'));
const buffer = Buffer.from(buff);
bufferMap.set(coordinates, buffer);
});
// and here in some way I need to return bufferMap obj
// to use it as input data in next cypress task:
})
.task('mergeImages', { buffers: bufferMap, savePath: 'cypress/snapshots' });
});
}
mergeImages
task will proceed the map and using specified sorting, merge all canvases to a single PNG
image. mergeImages
任务将处理地图并使用指定的排序,将所有画布合并为单个PNG
图像。
But is it possible in some way to return this map from each
command?但是有可能以某种方式从
each
命令返回这个映射吗?
This bufferMap
object valid only inside each command.这个
bufferMap
对象只在每个命令内部有效。 But out of each
it still empty但
each
它仍然是空的
cy.wprap()
also not resolve this issue. cy.wprap()
也不能解决这个问题。 Or I use it incorrect...或者我用错了...
Thanks!谢谢!
A couple of problems with the custom command自定义命令的几个问题
to make sure you wait on the results of .each()
, must return the promise created bt Cypress.Blob.canvasToBlob()
chain.为了确保您等待
.each()
的结果,必须返回创建的承诺Cypress.Blob.canvasToBlob()
链。
follow the .each()
with a .then()
to ensure completion, and return `bufferMap here.遵循
.each()
用.then()
以确保完成,并回到这里`bufferMap。
Problems with .task()
.task()
it does not like being called within the custom command, so call it after它不喜欢在自定义命令中被调用,所以在之后调用它
CypressError: cy.then() failed because you are mixing up async and sync code.
CypressError: cy.then() 失败,因为您混淆了异步和同步代码。
it does not like a Map()
object as a parameter, convert to a plain object它不喜欢
Map()
对象作为参数,转换为普通对象
Test测试
describe('leaflet', () => {
it('processes', () => {
Cypress.Commands.add('renderCanvasMatrixToPng', {prevSubject: true}, (subjects, savePath) => {
const bufferMap = new Map();
cy.wrap(subjects)
.each((canvas, i) => {
return Cypress.Blob.canvasToBlob(canvas.get(0)) // <- add return here
.then(blob => Cypress.Blob.blobToArrayBuffer(blob))
.then(buff => {
var view = new Int8Array(buff); // not sure why this is needed
const buffer = Buffer.from(view);
// get coords here
const coords = 1000 + i // for purpose of demo
bufferMap.set(coords, buffer)
})
})
.then(_ => { // <- wait for previous to complete
console.log('bufferMap inside command', bufferMap) // [[Entries]]
// 0: {0 => Uint8Array(27209)}
// 1: {1 => Uint8Array(1179)}
return bufferMap;
})
});
cy.visit('http://cartodb.github.io/Leaflet.CanvasLayer/example.html')
cy.get('canvas').renderCanvasMatrixToPng().then(bufferMap => {
console.log('bufferMap outside command', bufferMap) // [[Entries]]
// 0: {1000 => Uint8Array(25218)}
// 1: {1001 => Uint8Array(1179)}
const asObject = Object.fromEntries(bufferMap);
cy.task('mergeImages', { buffers: asObject, savePath: 'cypress/snapshots' });
})
})
})
Task for demo演示任务
module.exports = (on, config) => {
...
on('task', {
mergeImages(options) {
const { buffers, savePath } = options;
console.log('buffers', buffers);
/* In terminal
buffers {
'1000': {
type: 'Buffer',
data: [
137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13,
... 33137 more items
]
},
'1001': {
type: 'Buffer',
data: [
137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13,
... 1079 more items
]
}
}
*/
return null;
}
})
}
Alternative command (my preference)替代命令(我的偏好)
Cypress.Commands.add('renderCanvasMatrixToPng', { prevSubject: true }, (subjects, savePath) => {
const bufferPromises = Array.from(subjects).map(canvas => {
return Cypress.Blob.canvasToBlob(canvas)
.then(blob => Cypress.Blob.blobToArrayBuffer(blob))
.then(buff => {
const view = new Int8Array(buff);
const buffer = Buffer.from(view);
return buffer;
})
})
return Promise.all(bufferPromises).then(buffers => {
const bufferMap = new Map();
buffers.forEach((buffer, i) => {
// get coords here
const coords = 1000 + i // for purpose of demo
bufferMap.set(coords, buffer)
})
return bufferMap;
})
});
So I found the solution!所以我找到了解决方案!
Now it works pretty good for me.现在它对我来说效果很好。 Code sample:
代码示例:
function convertCanvasMatrixToPictureCommand() {
Cypress.Commands.add('renderCanvasMatrixToPng', { prevSubject: true }, (subject, writeTo) => {
const imgArr = [];
cy.wrap(subject)
.each(canvas =>
new Cypress.Promise(resolve => {
Cypress.Blob.canvasToBlob(canvas.get(0))
.then(blob => Cypress.Blob.blobToArrayBuffer(blob))
.then(arrayBuffer => {
const coordinates = extract(canvas.attr('style'));
imgArr.push({ id: coordinates, buffer: arrayBuffer });
resolve(true);
});
}))
.then(() => {
cy.task('mergeImages', {
imageArrayBuffers: imgArr,
outputFolder: writeTo,
});
});
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.