Skip to content

Commit a6c7067

Browse files
committed
Merge remote-tracking branch 'upstream'
2 parents e7438fd + d3ae82d commit a6c7067

3 files changed

Lines changed: 72 additions & 43 deletions

File tree

src/gametest/java/net/wurstclient/gametest/SingleplayerTest.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public SingleplayerTest(ClientGameTestContext context,
4646
public final void run()
4747
{
4848
runImpl();
49-
assertScreenshotEquals(
49+
waitForScreenshotMatch(
5050
getClass().getSimpleName().toLowerCase() + "_cleanup",
5151
"https://i.imgur.com/XF1SILt.png");
5252
}
@@ -131,6 +131,13 @@ protected final void assertScreenshotEquals(String fileName,
131131
templateUrl);
132132
}
133133

134+
protected final void waitForScreenshotMatch(String fileName,
135+
String templateUrl)
136+
{
137+
WurstClientTestHelper.waitForScreenshotMatch(context, fileName,
138+
templateUrl);
139+
}
140+
134141
protected final void failWithScreenshot(String fileName, String title,
135142
String errorMessage)
136143
{

src/gametest/java/net/wurstclient/gametest/WurstClientTestHelper.java

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -52,31 +52,62 @@ public static void assertScreenshotEquals(ClientGameTestContext context,
5252
String fileName, String templateUrl)
5353
{
5454
ThreadingImpl.checkOnGametestThread("assertScreenshotEquals");
55+
waitForScreenshotMatchImpl(context, fileName, templateUrl, 1);
56+
}
57+
58+
/**
59+
* Same as
60+
* {@link #assertScreenshotEquals(ClientGameTestContext, String, String)},
61+
* but retries for up to 10 seconds to get a matching screenshot.
62+
*
63+
* <p>
64+
* Useful for cases where you're waiting for recent movements to settle
65+
* (e.g. chunk reloads, hand animation), where it can otherwise be tricky to
66+
* get the timing right. Not useful for anything that's still in motion,
67+
* where delaying the screenshot would only cause it to drift further away
68+
* from the expected image.
69+
*/
70+
public static void waitForScreenshotMatch(ClientGameTestContext context,
71+
String fileName, String templateUrl)
72+
{
73+
ThreadingImpl.checkOnGametestThread("waitForScreenshotMatch");
74+
waitForScreenshotMatchImpl(context, fileName, templateUrl,
75+
ClientGameTestContext.DEFAULT_TIMEOUT);
76+
}
77+
78+
private static void waitForScreenshotMatchImpl(
79+
ClientGameTestContext context, String fileName, String templateUrl,
80+
int maxAttempts)
81+
{
82+
NativeImage nativeImageTemplate = downloadImage(templateUrl);
83+
boolean[][] mask = alphaChannelToMask(nativeImageTemplate);
84+
RawImage<int[]> rawTemplate =
85+
RawImageImpl.fromColorNativeImage(nativeImageTemplate);
86+
RawImage<int[]> maskedTemplate = applyMask(rawTemplate, mask);
5587

56-
NativeImage nativeTemplateImage = downloadImage(templateUrl);
57-
boolean[][] mask = alphaChannelToMask(nativeTemplateImage);
58-
RawImage<int[]> rawTemplateImage =
59-
RawImageImpl.fromColorNativeImage(nativeTemplateImage);
60-
RawImage<int[]> maskedTemplateImage = applyMask(rawTemplateImage, mask);
61-
62-
Path screenshotPath = context.takeScreenshot(fileName);
63-
RawImage<int[]> rawScreenshotImage =
64-
RawImageImpl.fromColorNativeImage(loadImageFile(screenshotPath));
65-
RawImage<int[]> maskedScreenshotImage =
66-
applyMask(rawScreenshotImage, mask);
67-
68-
if(maskedScreenshotImage.width() != maskedTemplateImage.width()
69-
|| maskedScreenshotImage.height() != maskedTemplateImage.height())
70-
throw new AssertionError(
71-
"Screenshot and template dimensions do not match");
72-
73-
TestScreenshotComparisonAlgorithm algo =
74-
TestScreenshotComparisonAlgorithm.meanSquaredDifference(3e-4F);
75-
76-
Vector2i result =
77-
algo.findColor(maskedScreenshotImage, maskedTemplateImage);
78-
if(result != null)
79-
return;
88+
Path screenshotPath = null;
89+
for(int i = 0; i < maxAttempts; i++)
90+
{
91+
if(i > 0)
92+
context.waitTick();
93+
94+
screenshotPath = context.takeScreenshot(fileName);
95+
RawImage<int[]> rawScreenshot = RawImageImpl
96+
.fromColorNativeImage(loadImageFile(screenshotPath));
97+
RawImage<int[]> maskedScreenshot = applyMask(rawScreenshot, mask);
98+
99+
if(maskedScreenshot.width() != maskedTemplate.width()
100+
|| maskedScreenshot.height() != maskedTemplate.height())
101+
throw new AssertionError(
102+
"Screenshot and template dimensions do not match");
103+
104+
TestScreenshotComparisonAlgorithm algo =
105+
TestScreenshotComparisonAlgorithm.meanSquaredDifference(3e-4F);
106+
107+
Vector2i result = algo.findColor(maskedScreenshot, maskedTemplate);
108+
if(result != null)
109+
return;
110+
}
80111

81112
ghSummary("### Screenshot " + fileName + " does not match template");
82113
ghSummary("Expected:");

src/gametest/java/net/wurstclient/gametest/tests/XRayHackTest.java

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,26 +33,26 @@ protected void runImpl()
3333
runWurstCommand("setcheckbox X-Ray only_show_exposed off");
3434
runWurstCommand("setslider X-Ray opacity 0");
3535
input.pressKey(GLFW.GLFW_KEY_X);
36-
waitForChunkReloading();
37-
assertScreenshotEquals("xray_default",
36+
world.waitForChunksRender();
37+
waitForScreenshotMatch("xray_default",
3838
"https://i.imgur.com/Dftamqv.png");
3939

4040
// Exposed only
4141
runWurstCommand("setcheckbox X-Ray only_show_exposed on");
4242
runWurstCommand("setslider X-Ray opacity 0");
4343
input.pressKey(GLFW.GLFW_KEY_X);
4444
input.pressKey(GLFW.GLFW_KEY_X);
45-
waitForChunkReloading();
46-
assertScreenshotEquals("xray_exposed_only",
45+
world.waitForChunksRender();
46+
waitForScreenshotMatch("xray_exposed_only",
4747
"https://i.imgur.com/QlEpQTu.png");
4848

4949
// Opacity mode
5050
runWurstCommand("setcheckbox X-Ray only_show_exposed off");
5151
runWurstCommand("setslider X-Ray opacity 0.5");
5252
input.pressKey(GLFW.GLFW_KEY_X);
5353
input.pressKey(GLFW.GLFW_KEY_X);
54-
waitForChunkReloading();
55-
assertScreenshotEquals("xray_opacity",
54+
world.waitForChunksRender();
55+
waitForScreenshotMatch("xray_opacity",
5656
WurstTest.IS_MOD_COMPAT_TEST ? "https://i.imgur.com/hXdzoDB.png"
5757
: "https://i.imgur.com/oZqevTx.png");
5858

@@ -61,8 +61,8 @@ protected void runImpl()
6161
runWurstCommand("setslider X-Ray opacity 0.5");
6262
input.pressKey(GLFW.GLFW_KEY_X);
6363
input.pressKey(GLFW.GLFW_KEY_X);
64-
waitForChunkReloading();
65-
assertScreenshotEquals("xray_exposed_only_opacity",
64+
world.waitForChunksRender();
65+
waitForScreenshotMatch("xray_exposed_only_opacity",
6666
WurstTest.IS_MOD_COMPAT_TEST ? "https://i.imgur.com/ZwIARSr.png"
6767
: "https://i.imgur.com/3DLxNuS.png");
6868

@@ -72,7 +72,7 @@ protected void runImpl()
7272
runWurstCommand("setcheckbox X-Ray only_show_exposed off");
7373
runWurstCommand("setslider X-Ray opacity 0");
7474
input.pressKey(GLFW.GLFW_KEY_X);
75-
waitForChunkReloading();
75+
world.waitForChunksRender();
7676
clearChat();
7777
}
7878

@@ -103,15 +103,6 @@ private void buildTestRig()
103103

104104
// Wait for blocks to appear
105105
waitForBlock(-1, 0, 6, Blocks.LAVA);
106-
waitForChunkReloading();
107106
clearChat();
108107
}
109-
110-
private void waitForChunkReloading()
111-
{
112-
// Wait longer if testing with Sodium, since we can't rely on
113-
// waitForChunksRender() to track when Sodium finishes loading chunks
114-
context.waitTicks(WurstTest.IS_MOD_COMPAT_TEST ? 5 : 1);
115-
world.waitForChunksRender();
116-
}
117108
}

0 commit comments

Comments
 (0)