From c78b39adf7a13198e97a211e8a7b304c2a695d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Lindstr=C3=B6m?= Date: Fri, 8 May 2026 14:17:58 +0300 Subject: [PATCH] fix: Improve viewport resizing behavior (backport of #2170) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Original description: The fix replaces the single-shot adjustment with a converging retry loop. The browser chrome (title bar, borders) is constant for a session. Iteration 1 discovers the offset, iteration 2 (or rarely 3) nails the target. 5 attempts is generous safety margin for unusual environments (remote grids, DPI scaling). Removes hardcoded Mac FF offsets that are irrelevant for modern browsers and cause unnecessary overshoot on other platforms (extrah=106, extraw=0) — starts with the desired dimensions directly Loops up to 5 times, each iteration measuring the actual viewport via JS, computing the diff, and adjusting the window size using the current window size (not accumulated offsets) Returns early as soon as the viewport matches the target Re-throws UnsupportedOperationException without wrapping, while wrapping other exceptions Logs each adjustment at debug level for troubleshooting Fixes: [#2167] --- .../commands/TestBenchCommandExecutor.java | 57 ++++++++++++------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/vaadin-testbench-core/src/main/java/com/vaadin/testbench/commands/TestBenchCommandExecutor.java b/vaadin-testbench-core/src/main/java/com/vaadin/testbench/commands/TestBenchCommandExecutor.java index 706500a56..d44f67a99 100644 --- a/vaadin-testbench-core/src/main/java/com/vaadin/testbench/commands/TestBenchCommandExecutor.java +++ b/vaadin-testbench-core/src/main/java/com/vaadin/testbench/commands/TestBenchCommandExecutor.java @@ -292,33 +292,48 @@ public WebDriver getDriver() { @Override public void resizeViewPortTo(final int desiredWidth, final int desiredHeight) throws UnsupportedOperationException { + final int MAX_RESIZE_ATTEMPTS = 5; try { - actualDriver.manage().window().setPosition(new Point(0, 0)); + getDriver().manage().window().setPosition(new Point(0, 0)); + // Start with the desired dimensions; the loop will adjust for + // browser chrome (title bar, borders, etc.) + getDriver().manage().window() + .setSize(new Dimension(desiredWidth, desiredHeight)); + + for (int attempt = 0; attempt < MAX_RESIZE_ATTEMPTS; attempt++) { + int actualWidth = detectViewportWidth(); + int actualHeight = detectViewportHeight(); + + if (actualWidth == desiredWidth + && actualHeight == desiredHeight) { + return; + } - // first try with mac FF, these will change from plat to plat and - // browser setup to another - int extrah = 106; - int extraw = 0; - actualDriver.manage().window().setSize(new Dimension( - desiredWidth + extraw, desiredHeight + extrah)); + int diffW = desiredWidth - actualWidth; + int diffH = desiredHeight - actualHeight; + Dimension currentSize = getDriver().manage().window().getSize(); + getLogger().fine( + "resizeViewPortTo: attempt " + (attempt + 1) + ", " + + "desired=" + desiredWidth + "x" + desiredHeight + ", " + + "actual=" + actualWidth + "x" + actualHeight + ", " + + "adjusting by " + diffW + "x" + diffH); + getDriver().manage().window() + .setSize(new Dimension(currentSize.getWidth() + diffW, + currentSize.getHeight() + diffH)); + } + // Final check after all attempts int actualWidth = detectViewportWidth(); int actualHeight = detectViewportHeight(); - - int diffW = desiredWidth - actualWidth; - int diffH = desiredHeight - actualHeight; - - if (diffH != 0 || diffW != 0) { - actualDriver.manage().window() - .setSize(new Dimension(desiredWidth + extraw + diffW, - desiredHeight + extrah + diffH)); - } - actualWidth = detectViewportWidth(); - actualHeight = detectViewportHeight(); - if (desiredWidth != actualWidth || desiredHeight != actualHeight) { - throw new Exception( - "Viewport size couldn't be set to desired."); + if (actualWidth != desiredWidth || actualHeight != desiredHeight) { + throw new UnsupportedOperationException( + "Viewport size couldn't be set to the desired '" + + desiredWidth + "," + desiredHeight + "' got '" + + actualWidth + "," + actualHeight + "' after " + + MAX_RESIZE_ATTEMPTS + " attempts."); } + } catch (UnsupportedOperationException e) { + throw e; } catch (Exception e) { throw new UnsupportedOperationException( "Viewport couldn't be adjusted.", e);