Feature("MIG");
|
|
const assert = require("assert");
|
|
const rectConfig = `
|
<View>
|
<Image name="img" valueList="$images"/>
|
<RectangleLabels name="tag" toName="img">
|
<Label value="Planet"></Label>
|
<Label value="Moonwalker" background="blue"></Label>
|
</RectangleLabels>
|
</View>
|
`;
|
|
const brushConfig = `
|
<View>
|
<Image name="img" valueList="$images"/>
|
<BrushLabels name="tag" toName="img">
|
<Label value="Planet"></Label>
|
<Label value="Moonwalker" background="blue"></Label>
|
</BrushLabels>
|
</View>
|
`;
|
|
const data = {
|
images: [
|
"https://data.heartex.net/open-images/train_0/mini/0030019819f25b28.jpg",
|
"https://data.heartex.net/open-images/train_0/mini/00155094b7acc33b.jpg",
|
"https://data.heartex.net/open-images/train_0/mini/00133643bbf063a9.jpg",
|
"https://data.heartex.net/open-images/train_0/mini/0061ec6e9576b520.jpg",
|
],
|
};
|
|
const result = [
|
{
|
original_width: 768,
|
original_height: 576,
|
image_rotation: 0,
|
value: {
|
x: 7.814060788954878,
|
y: 42.05253910374108,
|
width: 11.226011120078905,
|
height: 10.491211550533542,
|
rotation: 0,
|
rectanglelabels: ["Planet"],
|
},
|
id: "SBHuSbuOoI",
|
from_name: "tag",
|
to_name: "img",
|
type: "rectanglelabels",
|
origin: "manual",
|
item_index: 0,
|
},
|
{
|
id: "spPCrj0omt",
|
type: "rectanglelabels",
|
value: {
|
x: 40.237685381355924,
|
y: 22.88135593220339,
|
width: 7.878707627118645,
|
height: 18.64406779661017,
|
rotation: 0,
|
rectanglelabels: ["Moonwalker"],
|
},
|
origin: "manual",
|
to_name: "img",
|
from_name: "tag",
|
item_index: 1,
|
image_rotation: 0,
|
original_width: 768,
|
original_height: 510,
|
},
|
{
|
original_width: 768,
|
original_height: 576,
|
image_rotation: 0,
|
value: {
|
x: 37.190330463635505,
|
y: 50.85521215886758,
|
width: 15.008743610438549,
|
height: 14.539802110423578,
|
rotation: 0,
|
rectanglelabels: ["Planet"],
|
},
|
id: "4SkI4GVN4u",
|
from_name: "tag",
|
to_name: "img",
|
type: "rectanglelabels",
|
origin: "manual",
|
item_index: 0,
|
},
|
];
|
|
Before(async ({ LabelStudio }) => {
|
LabelStudio.setFeatureFlags({
|
fflag_feat_front_lsdv_4583_multi_image_segmentation_short: true,
|
});
|
});
|
|
Scenario("Image list rendering", async ({ I, LabelStudio, AtImageView }) => {
|
const params = {
|
config: rectConfig,
|
data,
|
annotations: [{ id: 1, result: [] }],
|
};
|
|
I.amOnPage("/");
|
LabelStudio.init(params);
|
|
LabelStudio.waitForObjectsReady();
|
await AtImageView.lookForStage();
|
|
I.seeElement(`img[src="${data.images[0]}"]`);
|
});
|
|
Scenario("Image list with page navigation", async ({ I, AtImageView, LabelStudio }) => {
|
const params = {
|
config: rectConfig,
|
data,
|
annotations: [{ id: 1, result: [] }],
|
};
|
|
const prevPageButton = locate(".lsf-pagination__btn.lsf-pagination__btn_arrow-left");
|
const nextPageButton = locate(".lsf-pagination__btn.lsf-pagination__btn_arrow-right");
|
|
I.amOnPage("/");
|
LabelStudio.init(params);
|
|
LabelStudio.waitForObjectsReady();
|
await AtImageView.lookForStage();
|
|
I.say("Loading first image");
|
I.seeElement(`img[src="${data.images[0]}"]`);
|
|
I.say("Pagination is visible");
|
I.seeElement(".lsf-pagination");
|
|
I.say("The number of pages is correct");
|
I.see("1 of 4");
|
|
I.say("Clicking on the next page");
|
I.click(nextPageButton);
|
|
I.say("Loading second image");
|
I.seeElement(`img[src="${data.images[1]}"]`);
|
I.see("2 of 4");
|
|
I.say("Clicking on the previous page");
|
I.click(prevPageButton);
|
I.seeElement(`img[src="${data.images[0]}"]`);
|
I.see("1 of 4");
|
});
|
|
Scenario("Image list with hotkey navigation", async ({ I, AtImageView, LabelStudio }) => {
|
const params = {
|
config: rectConfig,
|
data,
|
annotations: [{ id: 1, result: [] }],
|
};
|
|
I.amOnPage("/");
|
LabelStudio.init(params);
|
|
LabelStudio.waitForObjectsReady();
|
await AtImageView.lookForStage();
|
|
I.say("Loading first image");
|
I.seeElement(`img[src="${data.images[0]}"]`);
|
|
I.say("Pagination is visible");
|
I.seeElement(".lsf-pagination");
|
|
I.say("The number of pages is correct");
|
I.see("1 of 4");
|
|
await AtImageView.multiImageGoForwardWithHotkey();
|
|
I.say("Loading second image");
|
I.seeElement(`img[src="${data.images[1]}"]`);
|
I.see("2 of 4");
|
|
await AtImageView.multiImageGoBackwardWithHotkey();
|
I.seeElement(`img[src="${data.images[0]}"]`);
|
I.see("1 of 4");
|
});
|
|
Scenario("View All disables MIG pagination", async ({ I, AtImageView, LabelStudio }) => {
|
const params = {
|
config: rectConfig,
|
data,
|
annotations: [
|
{ id: 1, result: [] },
|
{ id: 2, result: [] },
|
],
|
additionalInterfaces: ["annotations:view-all"],
|
};
|
|
const prevSelector = ".lsf-pagination__btn_arrow-left";
|
const nextSelector = ".lsf-pagination__btn_arrow-right";
|
|
// FFs for a proper interface with View All button
|
LabelStudio.setFeatureFlags({
|
fflag_feat_front_dev_3873_labeling_ui_improvements_short: true,
|
});
|
|
I.amOnPage("/");
|
LabelStudio.init(params);
|
|
LabelStudio.waitForObjectsReady();
|
await AtImageView.lookForStage();
|
|
I.say("Move to next page to have a changed state");
|
I.click(locate(nextSelector));
|
I.seeElement(`img[src="${data.images[1]}"]`);
|
I.see("2 of 4");
|
|
I.say("Enable View All mode");
|
I.click('[aria-label="Compare all annotations"]');
|
|
I.say("Navigation buttons should be disabled");
|
I.seeElement(locate(`${nextSelector}[class$=disabled]`));
|
I.seeElement(locate(`${prevSelector}[class$=disabled]`));
|
I.see("2 of 4");
|
|
I.say("Hotkeys for navigation should not work");
|
await AtImageView.multiImageGoForwardWithHotkey();
|
I.seeElement(`img[src="${data.images[1]}"]`);
|
I.see("2 of 4");
|
|
await AtImageView.multiImageGoBackwardWithHotkey();
|
I.seeElement(`img[src="${data.images[1]}"]`);
|
I.see("2 of 4");
|
});
|
|
Scenario(
|
"Ensure that results are the same when exporting existing regions",
|
async ({ I, AtImageView, LabelStudio }) => {
|
const params = {
|
config: rectConfig,
|
data,
|
annotations: [{ id: 1, result }],
|
};
|
|
I.amOnPage("/");
|
LabelStudio.init(params);
|
|
LabelStudio.waitForObjectsReady();
|
await AtImageView.lookForStage();
|
|
I.say("Result must be exactly the same as we're not modifying anything");
|
await LabelStudio.resultsNotChanged(result);
|
},
|
);
|
|
Scenario("Image list exports correct data", async ({ I, LabelStudio, AtImageView }) => {
|
const params = {
|
config: rectConfig,
|
data,
|
annotations: [{ id: 1, result }],
|
};
|
|
I.amOnPage("/");
|
LabelStudio.init(params);
|
|
LabelStudio.waitForObjectsReady();
|
await AtImageView.lookForStage();
|
|
AtImageView.multiImageGoForwardWithHotkey();
|
|
LabelStudio.waitForObjectsReady();
|
await AtImageView.lookForStage();
|
I.seeElement(`img[src="${data.images[1]}"]`);
|
|
await LabelStudio.resultsNotChanged(result);
|
});
|
|
Scenario("Regions are not changes when duplicating an annotation", async ({ I, LabelStudio, AtImageView }) => {
|
const params = {
|
config: rectConfig,
|
data,
|
annotations: [{ id: 1, result }],
|
};
|
|
I.amOnPage("/");
|
LabelStudio.init(params);
|
|
LabelStudio.waitForObjectsReady();
|
await AtImageView.lookForStage();
|
|
I.say("Attempting to duplicate an annotaion");
|
I.click('[aria-label="Copy Annotation"]');
|
|
LabelStudio.waitForObjectsReady();
|
await AtImageView.lookForStage();
|
|
I.say("Confirm that result is not changed");
|
await LabelStudio.resultsNotChanged(result);
|
});
|
|
Scenario("No errors during brush export in MIG", async ({ I, LabelStudio, AtImageView, AtLabels, AtPanels }) => {
|
const params = {
|
config: brushConfig,
|
data,
|
annotations: [{ id: 1, result: [] }],
|
};
|
|
const brushRegionPoints = [
|
[20, 20],
|
[20, 40],
|
[40, 40],
|
[40, 20],
|
[20, 20],
|
];
|
const AtDetailsPanel = AtPanels.usePanel(AtPanels.PANEL.DETAILS);
|
|
I.amOnPage("/");
|
LabelStudio.init(params);
|
AtDetailsPanel.collapsePanel();
|
|
LabelStudio.waitForObjectsReady();
|
await AtImageView.lookForStage();
|
|
I.say("Create brush regions on the first image");
|
AtLabels.clickLabel("Moonwalker");
|
AtImageView.drawThroughPoints(brushRegionPoints);
|
|
// @todo: We cannot use these hotkeys due to duplicating regions action used the same hotkey
|
// await AtImageView.multiImageGoForwardWithHotkey();
|
await AtImageView.multiImageGoForward();
|
|
I.pressKey("u");
|
I.say("Create brush regions on the second image");
|
AtLabels.clickLabel("Planet");
|
AtImageView.drawThroughPoints(brushRegionPoints);
|
|
// Brush might not have a chance to finish whatewer it's
|
// doing, so it's safer to wait a little before exporting it
|
I.wait(2);
|
|
const result = await LabelStudio.serialize();
|
|
assert.equal(result.length, 2);
|
});
|