Bin
2025-12-16 9e0b2ba2c317b1a86212f24cbae3195ad1f3dbfa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
const assert = require("assert");
 
Feature("Zoomed transforms").tag("@regress");
 
const IMAGE =
  "https://htx-pub.s3.us-east-1.amazonaws.com/examples/images/nick-owuor-astro-nic-visuals-wDifg5xc9Z4-unsplash.jpg";
 
const config = `
  <View>
    <Image name="img" value="$image" zoomby="2"/>
    <Rectangle name="rect" toName="img"/>
  </View>`;
 
Scenario(
  "Transforming the region on the border of zoomed image",
  async ({ I, LabelStudio, AtImageView, AtOutliner }) => {
    const params = {
      config,
      data: { image: IMAGE },
    };
 
    I.amOnPage("/");
 
    LabelStudio.init(params);
    LabelStudio.waitForObjectsReady();
    AtOutliner.seeRegions(0);
 
    // Zoom in
    I.click("[aria-label='zoom-in']");
 
    await AtImageView.lookForStage();
    const width = AtImageView.percToX(100);
    const height = AtImageView.percToY(100);
 
    // Pan image to the left to see its right border
    I.pressKeyDown("Shift");
    AtImageView.drawByDrag(width - 10, height / 2, -width + 20, 0);
    I.pressKeyUp("Shift");
    // Create the region at the right border of the image
    AtImageView.drawByDrag(width - 30, height / 2, 20, height / 2 - 10);
    AtOutliner.seeRegions(1);
    // Select this region
    AtImageView.clickAt(width - 20, height / 2 + 10);
    AtOutliner.seeSelectedRegion();
    // Rotate by the rotator anchor (heuristically calculated coordinates)
    AtImageView.drawThroughPoints(
      [
        [width - 20, height / 2 - 50],
        [width / 2, height / 2],
      ],
      "steps",
      50,
    );
 
    const results = await LabelStudio.serialize();
 
    // The angle of rotation should not exceed 30 degrees
    assert.strictEqual((results[0].value.rotation + 30) % 360 < 30, true);
  },
);
 
Scenario(
  "Transforming the region on the border of zoomed image after window resize",
  async ({ I, LabelStudio, AtImageView, AtOutliner }) => {
    const wWidth = 1200;
    const wHeight = 900;
    const wWidthSmall = 1000;
 
    const params = {
      config,
      data: { image: IMAGE },
    };
 
    I.amOnPage("/");
    I.resizeWindow(wWidthSmall, wHeight);
 
    LabelStudio.init(params);
    LabelStudio.waitForObjectsReady();
    AtOutliner.seeRegions(0);
 
    // Zoom in
    I.click("[aria-label='zoom-in']");
 
    await AtImageView.lookForStage();
    const width = AtImageView.percToX(100);
    const height = AtImageView.percToY(100);
 
    // Pan image to the left to see its right border
    I.pressKeyDown("Shift");
    AtImageView.drawByDrag(width - 10, height / 2, -width + 20, 0);
    I.pressKeyUp("Shift");
 
    // Create the region at the right border of the image
    AtImageView.drawByDrag(width - 30, height / 2, 20, height / 2);
    AtOutliner.seeRegions(1);
    // Select this region
    AtImageView.clickAt(width - 20, height / 2 + 10);
    AtOutliner.seeSelectedRegion();
 
    I.resizeWindow(wWidth, wHeight);
 
    I.waitTicks(3);
 
    // If the canvas does not match the image, this action will rotate the region
    AtImageView.drawThroughPoints(
      [
        [width - 20, height / 2 - 50],
        [width / 2, height / 2 - 50],
      ],
      "steps",
      50,
    );
 
    const results = await LabelStudio.serialize();
 
    // But we do not want to rotate it.
    assert.strictEqual(results[0].value.rotation, 0);
  },
);