smoke.test.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. const { serialize } = require("./helpers");
  2. const Utils = require("../examples/utils");
  3. const examples = [
  4. require("../examples/audio-regions"),
  5. require("../examples/audio-paragraphs"),
  6. require("../examples/image-bboxes"),
  7. require("../examples/image-ellipses"),
  8. require("../examples/image-keypoints"),
  9. require("../examples/image-polygons"),
  10. require("../examples/ner-url"),
  11. require("../examples/nested"),
  12. require("../examples/text-html"),
  13. require("../examples/text-paragraphs"),
  14. require("../examples/timeseries-url-indexed"),
  15. ];
  16. const assert = require("assert");
  17. function roundFloats(struct) {
  18. return JSON.parse(
  19. JSON.stringify(struct, (key, value) => {
  20. if (typeof value === "number") {
  21. return value.toFixed(1);
  22. }
  23. return value;
  24. }),
  25. );
  26. }
  27. function assertWithTolerance(actual, expected) {
  28. assert.deepEqual(roundFloats(actual), roundFloats(expected));
  29. }
  30. Feature("Smoke test through all the examples");
  31. // old audio is broken, so skipping it
  32. examples.slice(1).forEach((example) =>
  33. Scenario(
  34. example.title || "Noname smoke test",
  35. async ({ I, LabelStudio, AtOutliner, AtTopbar, AtDetails, AtAudioView }) => {
  36. LabelStudio.setFeatureFlags({
  37. ff_front_dev_2715_audio_3_280722_short: true,
  38. });
  39. // @todo optional predictions in example
  40. const { annotations, config, data, result = annotations[0].result } = example;
  41. const params = { annotations: [{ id: "test", result }], config, data };
  42. const configTree = Utils.parseXml(config);
  43. const ids = [];
  44. // add all unique ids from non-classification results
  45. // @todo some classifications will be reflected in Results list soon
  46. result.forEach((r) => !ids.includes(r.id) && Object.keys(r.value).length > 1 && ids.push(r.id));
  47. const count = ids.length;
  48. await I.amOnPage("/");
  49. LabelStudio.init(params);
  50. AtOutliner.seeRegions(count);
  51. let restored;
  52. LabelStudio.waitForObjectsReady();
  53. if (Utils.xmlFindBy(configTree, (node) => node["#name"] === "Audio")) {
  54. await AtAudioView.waitForAudio();
  55. }
  56. if (Utils.xmlFindBy(configTree, (node) => ["text", "hypertext"].includes(node["#name"].toLowerCase()))) {
  57. I.waitForVisible(".lsf-htx-richtext", 5);
  58. }
  59. I.dontSeeElement(locate(".lsf-errors"));
  60. restored = await I.executeScript(serialize);
  61. assertWithTolerance(restored, result);
  62. if (count) {
  63. AtOutliner.clickRegion(1);
  64. // I.click('Delete Entity') - it founds something by tooltip, but not a button
  65. // so click the bin button in entity's info block
  66. AtDetails.clickDeleteRegion();
  67. AtOutliner.seeRegions(count - 1);
  68. AtTopbar.clickAria("Reset");
  69. AtOutliner.seeRegions(count);
  70. // Reset is undoable
  71. AtTopbar.clickAria("Undo");
  72. // so after all these manipulations first region should be deleted
  73. restored = await I.executeScript(serialize);
  74. assertWithTolerance(
  75. restored,
  76. result.filter((r) => r.id !== ids[0]),
  77. );
  78. }
  79. // Click on annotation copy button
  80. AtTopbar.clickAria("Copy Annotation");
  81. // Check if new annotation exists
  82. AtTopbar.seeAnnotationAt(2);
  83. // Check for regions count
  84. AtOutliner.seeRegions(count);
  85. await I.executeScript(async () => {
  86. // await window.LabelStudio.destroyAll();
  87. // return true;
  88. });
  89. },
  90. ),
  91. );