因此,我编写了TAF以使用赛普拉斯实现用户案例的自动化。我是新手。
我需要从赛普拉斯each
命令返回一个Map
,其中包含一些值,以便在下一个命令中将其用作输入值。
在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>
我需要从style
属性中提取两个坐标,因此,只需变换值即可:
width: 256px; height: 256px; transform: translate3d(613px, 246px, 0px); opacity: 1;
到
613 246
并将其设置为Map对象的键。作为值,我需要设置一个编码画布数据的缓冲区。
因此,我添加了这样的自定义命令:
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
任务将继续执行地图,并使用指定的排序,将所有画布合并到单个PNG
图像中。
但是可以通过某种方式从each
命令返回此映射吗?
此bufferMap
对象仅在每个命令中有效。但是在each
中,它仍然是空的
cy.wprap()
也无法解决此问题。还是我使用不正确...
谢谢!
答案 0 :(得分:3)
自定义命令的几个问题
以确保您等待.each()
的结果,必须返回由promise创建的bt Cypress.Blob.canvasToBlob()
链。
在.each()
之后跟随.then()
以确保完成,并在此处返回`bufferMap。
.task()
的问题
它不喜欢在自定义命令中调用,因此请在之后调用它
CypressError:cy.then()失败,因为您混淆了异步和同步代码。
它不喜欢将Map()
对象作为参数,而是转换为普通对象
测试
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' });
})
})
})
演示任务
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;
}
})
}
替代命令(我的偏好)
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;
})
});
答案 1 :(得分:0)
所以我找到了解决方案!
现在对我来说效果很好。代码示例:
var dailyUpdates = await _context.CoStatusUpdates
.Include(x => x.CoStatus)
.Include(x => x.Company)
.ThenInclude(x => x.Organisation)
.Where(x => !x.Company.Organisation.IsDeleted
&& x.Company.Organisation.OrganisationTypeId == organisationTypeId))
.ToListAsync();
var result = dailyUpdates.GroupBy(p => p.CompanyId)
.Select(x => new CoStatusUpdate
{
CompanyId = x.Key,
Company = new Company() //building new object for the only fields we need otherwise there's way more returned than needed
{
Organisation = new Organisation()
{
Name = x.FirstOrDefault(y => y.SubmittedDateTime == x.Max(z => z.SubmittedDateTime)).Company.Organisation.Name,
IsDeleted = x.FirstOrDefault(y => y.SubmittedDateTime == x.Max(z => z.SubmittedDateTime)).Company.Organisation.IsDeleted,
OrganisationTypeId = x.FirstOrDefault(y => y.SubmittedDateTime == x.Max(z => z.SubmittedDateTime)).Company.Organisation.OrganisationTypeId,
}
},
CoStatusUpdateId = x.FirstOrDefault(y => y.SubmittedDateTime == x.Max(z => z.SubmittedDateTime)).CoStatusUpdateId,
CoStatusId = x.FirstOrDefault(y => y.SubmittedDateTime == x.Max(z => z.SubmittedDateTime)).CoStatusId,
CoStatus = x.FirstOrDefault(y => y.SubmittedDateTime == x.Max(z => z.SubmittedDateTime)).CoStatus,
SubmittedDateTime = x.Max(z => z.SubmittedDateTime)
})
.ToDictionary(x => x.CompanyId);