| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- const { doDrawingAction, hasKonvaPixelColorAtPoint, setKonvaLayersOpacity, serialize } = require("./helpers");
- const assert = require("assert");
- Feature("Test Image Magic Wand");
- const CLOUDSHADOW = {
- color: "#1EAE3B",
- rgbArray: [30, 174, 59],
- };
- const HAZE = {
- color: "#68eee5",
- rgbArray: [104, 238, 229],
- };
- const CLOUD = {
- color: "#1b32de",
- rgbArray: [27, 50, 222],
- };
- const config = `
- <View>
- <Labels name="labels_1" toName="image_1">
- <Label hotkey="1" value="Snow" background="#F61E33" />
- <Label hotkey="2" value="Cloud Shadow" background="${CLOUDSHADOW.color}" />
- <Label hotkey="3" value="Haze" background="${HAZE.color}" />
- <Label hotkey="4" value="Cloud" background="${CLOUD.color}" />
- <Label hotkey="5" value="Exclude" background="#2C2C2B" />
- </Labels>
- <MagicWand name="magicwand_1" toName="image_1" />
- <View style="width: 100%; margin-bottom: 20%; margin-side: 10%;">
- <Image name="image_1" value="$image" zoomControl="true" zoom="true" crossOrigin="anonymous" />
- </View>
- </View>`;
- const annotationEmpty = {
- id: "1000",
- result: [],
- };
- const data = {
- image: [
- "http://htx-pub.s3.amazonaws.com/samples/magicwand/magic_wand_scale_1_20200902_015806_26_2235_1B_AnalyticMS_00750_00750.jpg",
- "http://htx-pub.s3.amazonaws.com/samples/magicwand/magic_wand_scale_2_20200902_015806_26_2235_1B_AnalyticMS_00750_00750.jpg",
- "http://htx-pub.s3.amazonaws.com/samples/magicwand/magic_wand_scale_3_20200902_015806_26_2235_1B_AnalyticMS_00750_00750.jpg",
- "http://htx-pub.s3.amazonaws.com/samples/magicwand/magic_wand_false_color_20200902_015806_26_2235_1B_AnalyticMS_00750_00750.jpg",
- ],
- thumb:
- "http://htx-pub.s3.amazonaws.com/samples/magicwand/magic_wand_thumbnail_20200902_015806_26_2235_1B_AnalyticMS_00750_00750.jpg",
- };
- async function assertMagicWandPixel(I, x, y, assertValue, rgbArray, msg) {
- const hasPixel = await I.executeScript(hasKonvaPixelColorAtPoint, [x, y, rgbArray, 1]);
- assert.equal(hasPixel, assertValue, msg);
- }
- Scenario(
- "Make sure the magic wand works in a variety of scenarios",
- async ({ I, LabelStudio, AtImageView, AtOutliner, AtPanels }) => {
- const AtDetailsPanel = AtPanels.usePanel(AtPanels.PANEL.DETAILS);
- const params = {
- config,
- data,
- annotations: [annotationEmpty],
- };
- I.amOnPage("/");
- LabelStudio.init(params);
- AtDetailsPanel.collapsePanel();
- LabelStudio.waitForObjectsReady();
- await AtImageView.lookForStage();
- I.say("Making sure magic wand button is present");
- I.seeElement('.lsf-toolbar__group button[aria-label="magicwand"]');
- I.say("Making sure Eraser button is present");
- I.seeElement('.lsf-toolbar__group button[aria-label="eraser"]');
- I.say("Select magic wand & cloud class");
- I.pressKey("W");
- I.pressKey("4");
- AtOutliner.seeRegions(0);
- I.say("Magic wanding clouds with cloud class in upper left of image");
- await doDrawingAction(I, { msg: "Fill in clouds upper left", fromX: 454, fromY: 184, toX: 650, toY: 644 });
- I.waitTicks(2);
- await doDrawingAction(I, { msg: "Fill in clouds lower left", fromX: 454, fromY: 834, toX: 650, toY: 644 });
- I.waitTicks(2);
- I.say("Ensuring repeated magic wands back to back with same class collapsed into single region");
- AtOutliner.seeRegions(1);
- AtOutliner.see("Cloud");
- // Force all the magic wand regions to be a consistent color with no opacity to make testing
- // magic wand pixel colors more robust.
- I.say("Ensuring cloud magic wand pixels are correctly filled color");
- await I.executeScript(setKonvaLayersOpacity, [1.0]);
- await assertMagicWandPixel(
- I,
- 0,
- 0,
- false,
- CLOUD.rgbArray,
- "Far upper left corner should not have magic wand cloud class",
- );
- await assertMagicWandPixel(I, 260, 50, true, CLOUD.rgbArray, "Upper left should have magic wand cloud class");
- await assertMagicWandPixel(I, 300, 620, true, CLOUD.rgbArray, "Lower left should have magic wand cloud class");
- await assertMagicWandPixel(
- I,
- 675,
- 650,
- false,
- CLOUD.rgbArray,
- "Far lower right corner should not have magic wand cloud class",
- );
- // Make sure the region made from this is correct.
- I.say("Ensuring magic wand brushregion was created correctly");
- const result = await I.executeScript(serialize);
- const entry = result[1];
- assert.equal(entry.from_name, "labels_1");
- assert.equal(entry.type, "labels");
- const labels = entry.value.labels;
- assert.equal(labels.length, 1);
- assert.equal(labels[0], "Cloud");
- assert.equal(entry.value.rle.length > 0, true);
- // Undo the bottom left area we just added, make sure its gone but our region list is still
- // 1, then redo it and ensure its back and our region list is still 1 again.
- I.say("Undoing last cloud magic wand and ensuring it worked correctly");
- I.click('button[aria-label="Undo"]');
- I.waitTicks(2);
- await assertMagicWandPixel(
- I,
- 300,
- 620,
- false,
- CLOUD.rgbArray,
- "Undone lower left should not have magic wand cloud class anymore",
- );
- await assertMagicWandPixel(I, 260, 50, true, CLOUD.rgbArray, "Upper left should still have magic wand cloud class");
- AtOutliner.seeRegions(1);
- I.say("Redoing last cloud magic wand and ensuring it worked correctly");
- I.click('button[aria-label="Redo"]');
- I.waitTicks(2);
- await assertMagicWandPixel(
- I,
- 300,
- 620,
- true,
- CLOUD.rgbArray,
- "Redone lower left should have magic wand cloud class again",
- );
- await assertMagicWandPixel(I, 260, 50, true, CLOUD.rgbArray, "Upper left should still have magic wand cloud class");
- AtOutliner.seeRegions(1);
- I.say("Unselecting last magic wand region");
- I.pressKey("Escape");
- // @todo currently gallery doesn't work well with CORS, so this is not covered by test
- // Change to the false color view, zoom in, and magic wand with a new class.
- // I.say('Changing to false-color view');
- // I.click('[class*="gallery--"] img[src*="false_color"]');
- I.say("Zooming in");
- I.click('button[aria-label="zoom-in"]');
- I.click('button[aria-label="zoom-in"]');
- I.click('button[aria-label="zoom-in"]');
- I.click('button[aria-label="zoom-in"]');
- I.click('button[aria-label="zoom-in"]');
- I.say("Selecting cloud shadow class");
- I.pressKey("2");
- I.say("Magic wanding cloud shadows with cloud shadow class in center of zoomed image");
- await doDrawingAction(I, { msg: "Cloud shadow in middle of image", fromX: 600, fromY: 500, toX: 500, toY: 500 });
- I.waitTicks(2);
- I.say("Ensuring new cloud shadow magic wand region gets added to sidebar");
- AtOutliner.seeRegions(2);
- AtOutliner.see("Cloud Shadow");
- I.say("Ensuring cloud shadow magic wand pixels are correctly filled color");
- await I.executeScript(setKonvaLayersOpacity, [1.0]);
- await assertMagicWandPixel(
- I,
- 0,
- 0,
- false,
- CLOUDSHADOW.rgbArray,
- "Zoomed upper left corner should not have cloud shadow",
- );
- await assertMagicWandPixel(
- I,
- 350,
- 360,
- true,
- CLOUDSHADOW.rgbArray,
- "Center area should have magic wand cloud shadow class",
- );
- // Make sure if you have a region selected then change the class the region class changes.
- I.say("Changing class of existing selected region to Haze should change it to new class");
- I.pressKey("3");
- AtOutliner.seeRegions(2);
- AtOutliner.dontSee("Cloud Shadow");
- AtOutliner.see("Haze");
- I.waitTicks(2);
- await I.executeScript(setKonvaLayersOpacity, [1.0]);
- await assertMagicWandPixel(I, 350, 360, true, HAZE.rgbArray, "Center area should have magic wand haze class");
- },
- );
|