I recently noticed a new kind of flaky tests on the slow free tier GitHub Action runners: Integration tests were running on smaller screen sizes than specified in the device metrics. The root cause was the use of Selenium's page.driver.resize_window_to methods, which 
  by design
  
    Show archive.org snapshot
  
 does not block until the resizing process has settled:
We discussed this issue again recently, and agreed that windows size manipulation operations are asynchronous by nature, because we can't control window rendering effects added by a window manager, and browsers don't provide a callback that would allow to detect the end of windows size changing process.
Capybara provides a better way to manipulate the browser window which you should use instead: page.current_window.resize_to.
Good: Capybara::Window#resize_to
 
page.current_window.resize_to(width, height)
Reason
Capybara#Window#resize_to blocks until the window size equals the expected dimensions.
# Source code of #resize_to for additional context:
class Capybara::Window
  def resize_to(width, height)
    wait_for_stable_size { @driver.resize_window_to(handle, width, height) }
  end
  
  def wait_for_stable_size(seconds = session.config.default_max_wait_time)
    res = yield if block_given?
    timer = Capybara::Helpers.timer(expire_in: seconds)
    loop do
      prev_size = size
      sleep 0.025
      return res if prev_size == size
      break if timer.expired?
    end
    raise Capybara::WindowError, "Window size not stable within #{seconds} seconds."
  end
end
Bad: Capybara::Selenium::Driver#resize_window_to
 
page.driver.resize_window_to(page.driver.current_window_handle, width, height)
Reason
It's the same as above, but without a hard requirement for the resizing to settle. It will wait for at most 250ms before moving on.
# Source code of #resize_window_to for additional context:
class Capybara::Selenium::Driver
  def resize_window_to(handle, width, height)
    within_given_window(handle) do
      browser.manage.window.resize_to(width, height)
    end
  rescue Selenium::WebDriver::Error::UnknownError => e
    raise unless e.message.include?('failed to change window state')
    # Chromedriver doesn't wait long enough for state to change when coming out of fullscreen
    # and raises unnecessary error. Wait a bit and try again.
    sleep 0.25
    within_given_window(handle) do
      browser.manage.window.resize_to(width, height)
    end
  end
end
 
class Selenium::WebDriver::Window
  def resize_to(width, height)
    @bridge.resize_window Integer(width), Integer(height)
  end
end
 
class Selenium::WebDriver::Remote::Bridge
  def resize_window(width, height, handle = :current)
    raise Error::WebDriverError, 'Switch to desired window before changing its size' unless handle == :current
   # Chromedriver API call named "set_window_rect"
    set_window_rect(width: width, height: height)
  end
end
A note on device emulations
We usually define multiple device emulations with different screen resolutions in our Capybara config:
Capybara.register_driver(:desktop) { ... }
Capybara.register_driver(:tablet) { ... }
Capybara.register_driver(:mobile) { ... }
If you resize your entire spec using the driver: :tablet tag, you should be fine as we didn't notice any issues yet. Otherwise you could resize your window before every example just to be sure:
RSpec.configure do |config|
  config.before(type: :feature) do
    case Capybara.current_driver
    when :desktop
      resize_browser_to(DESKTOP_WIDTH, DESKTOP_HEIGHT)
    when :tablet
      resize_browser_to(TABLET_WIDTH, TABLET_HEIGHT)
    when :mobile
      resize_browser_to(MOBILE_WIDTH, MOBILE_HEIGHT)
    else
      # Nothing to do in case of rack tests
    end
  end
end
This could however reduce your test performance.