Как вернуть объект Map из Cypress каждый? - PullRequest
1 голос
/ 17 февраля 2020

Итак, я пишу TAF для автоматизации пользовательских случаев с использованием Cypress. Я новичок в этом.

Мне нужно вернуться из Cypress each команда a 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

и установите его как ключ к объекту карты. И в качестве значения мне нужно установить буфер закодированных данных холста.

Итак, я добавляю пользовательскую команду следующим образом:

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() также не решает эту проблему. Или я использую это неправильно ...

Спасибо!

Ответы [ 2 ]

2 голосов
/ 18 февраля 2020

Несколько проблем с пользовательской командой

  • , чтобы убедиться, что вы ожидаете результатов .each(), должны вернуть созданное обещание bt Cypress.Blob.canvasToBlob() chain.

  • следуйте .each() с .then(), чтобы гарантировать завершение, и возвращайте здесь `bufferMap.

Проблемы с .task()

  • он не любит, когда его вызывают в пользовательской команде, поэтому вызывайте его после

    CypressError: cy.then () не удалось, потому что вы смешиваете asyn c и syn c код.

  • он не похож на 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;
  })
});
0 голосов
/ 27 февраля 2020

Итак, я нашел решение!

Теперь оно работает довольно хорошо для меня. Пример кода:

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,
        });
      });
  });
}
...