t.me/atinfo_chat Telegram группа по автоматизации тестирования

Браузер не подключается к интернету при включенном прокси

Теги: #<Tag:0x00007fd776c3dea8> #<Tag:0x00007fd776c3db88>

Мне необходимо подменить ответ от сервера для того, чтобы получить определенные данные на UI.
Делаю я это следующим образом:

public class SelenideProxyExample {
    @BeforeAll
    public static void setup() {
        Configuration.proxyEnabled = true;
        open();
    }

    @Test
    public void testProxy(){
        SelenideProxyServer proxy = getSelenideProxy();
        proxy.addRequestFilter("proxy-usages.request", ((request, contents, messageInfo) -> {
            String url = messageInfo.getUrl();
            System.out.println(url + "\n\n" + contents.getTextContents());
            return null;
        }));
        open("https://dsternlicht.github.io/RESTool/");
    }
}

В результате открывается браузер, но не указанная в последней строке страница. Браузер не имеет доступа к интернету.

Использую следующие зависимости:

implementation (
            "com.codeborne:selenide:5.15.0",
            "com.browserup:browserup-proxy-core:2.1.1",
)

Запуск происходит локально через gradle test.
В адресной строке какой-то время находится адрес data:,.

Проблема воспроизводится как в chrome:86.0, так и в firefox:82.0.

open - убрать
proxyServer. - наверно, надо proxy. ?

Если убрать open(), то прокси не будет стартовать.
open() по сути стартует сессию браузера и прокси.

proxyServer - да, там proxy, описка вышла. Поправил изначальный пост.

Чтобы прокси запустить надо выполнить
proxy.start();
И в итоге что-то такое:

    @BeforeAll
    public static void setup() {
        Configuration.proxyEnabled = true;
		SelenideProxyServer proxy = getSelenideProxy();
        proxy.start();
    }

До выполнения

SelenideProxyServer proxy = getSelenideProxy();

прокси уже должен быть запущен. Вызывается метод getSelenideProxy() и, судя даже по названию, он подразумевает, что прокси уже запущен. А запускается он за счет открытия браузера и настройки Configuration.proxyEnabled = true.

Я также попробовал убрать open() и SelenideProxyServer proxy = getSelenideProxy();, заменив это на

SelenideProxyServer proxy = new SelenideProxyServer(new StaticConfig(), null);
proxy.start();

В результате при открытии браузера получил ошибку ERR_TUNNEL_CONNECTION_FAILED.

Пример я взял показательный от сюда: https://www.slideshare.net/QAFest/qa-fest-2019-selenide, слайды 52 и 53.

Класс! Я как раз вчера тоже нарвался на эту проблему, и знаю, как исправить. :slight_smile:

@ahanziuk Можешь приложить полный лог при запуске тестов?
У меня, например, в логах видна такая ошибка, и именно она и была причиной:

java.lang.NoSuchMethodError: 'int io.netty.buffer.ByteBuf.maxFastWritableBytes()
  at io.netty.handler.codec.ByteToMessageDecoder$1.cumulate(ByteToMessageDecoder.java:86)

Если запускать через первый вариант (SelenideProxyServer proxy = getSelenideProxy()),
то стектрейс такой:

2020-11-17 12:32:25,712 | INFO  | c.c.selenide.impl.WebDriverThreadLocalContainer | No webdriver is bound to current thread: 13 - let's create a new webdriver
2020-11-17 12:32:27,243 | INFO  | org.littleshoot.proxy.impl.DefaultHttpProxyServer | Starting proxy at address: 0.0.0.0/0.0.0.0:0
2020-11-17 12:32:27,324 | INFO  | org.littleshoot.proxy.impl.DefaultHttpProxyServer | Proxy listening with TCP transport
2020-11-17 12:32:27,533 | INFO  | org.littleshoot.proxy.impl.DefaultHttpProxyServer | Proxy started at address: /0:0:0:0:0:0:0:0:60908
2020-11-17 12:32:27,556 | INFO  | com.codeborne.selenide.impl.FileHelper | Creating folder: /<somePath>/build/downloads/1605612747553_54614_13
2020-11-17 12:32:27,792 | INFO  | io.github.bonigarcia.wdm.WebDriverManager | Using chromedriver 86.0.4240.22 (resolved driver for Chrome 86)
2020-11-17 12:32:27,829 | INFO  | io.github.bonigarcia.wdm.WebDriverManager | Exporting webdriver.chrome.driver as /Users/anatolii/.cache/selenium/chromedriver/mac64/86.0.4240.22/chromedriver
2020-11-17 12:32:27,909 | INFO  | c.c.selenide.webdriver.AbstractDriverFactory | Write webdriver logs to: <somePath>/build/reports/tests/webdriver.1605612747909_54614_13.log
Starting ChromeDriver 86.0.4240.22 (398b0743353ff36fb1b82468f63a3a93b4e2e89e-refs/branch-heads/4240@{#378}) on port 19057
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
ChromeDriver was started successfully.
Nov 17, 2020 12:32:31 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
2020-11-17 12:32:31,383 | INFO  | com.codeborne.selenide.webdriver.BrowserResizer | Set browser size to 1200x800
2020-11-17 12:32:31,680 | ERROR | org.littleshoot.proxy.impl.ClientToProxyConnection | (AWAITING_INITIAL) [id: 0x33111ff4, L:/192.168.0.104:60908 - R:/192.168.0.104:60924]: Caught an exception on ClientToProxyConnection
java.lang.NoSuchMethodError: io.netty.buffer.ByteBuf.isContiguous()Z
	at io.netty.handler.codec.ByteToMessageDecoder$1.cumulate(ByteToMessageDecoder.java:83)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:274)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337)
	at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
	at org.littleshoot.proxy.impl.ProxyConnection$BytesReadMonitor.channelRead(ProxyConnection.java:686)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1408)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:930)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:677)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:612)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:529)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:491)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:905)
	at java.base/java.lang.Thread.run(Thread.java:834)
2020-11-17 12:32:32,100 | INFO  | com.codeborne.selenide.webdriver.WebDriverFactory | BrowserName=chrome Version=86.0.4240.198 Platform=MAC
2020-11-17 12:32:32,100 | INFO  | com.codeborne.selenide.webdriver.WebDriverFactory | Selenide v. 5.15.0
2020-11-17 12:32:32,100 | INFO  | com.codeborne.selenide.webdriver.WebDriverFactory | Selenium WebDriver v. 3.141.59 build time: 2018-11-14T08:17:03
2020-11-17 12:32:32,100 | INFO  | c.c.selenide.drivercommands.CreateDriverCommand | Create webdriver in current thread 13: ChromeDriver -> ChromeDriver: chrome on MAC (ef317a6fc4008c3e11ff4d8147cbfa84)
2020-11-17 12:32:32,209 | ERROR | org.littleshoot.proxy.impl.ClientToProxyConnection | (AWAITING_INITIAL) [id: 0xfe41a56f, L:/192.168.0.104:60908 - R:/192.168.0.104:60926]: Caught an exception on ClientToProxyConnection
java.lang.NoSuchMethodError: io.netty.buffer.ByteBuf.isContiguous()Z
	at io.netty.handler.codec.ByteToMessageDecoder$1.cumulate(ByteToMessageDecoder.java:83)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:274)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337)
	at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
	at org.littleshoot.proxy.impl.ProxyConnection$BytesReadMonitor.channelRead(ProxyConnection.java:686)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1408)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:930)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:677)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:612)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:529)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:491)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:905)
	at java.base/java.lang.Thread.run(Thread.java:834)

и получаю ERR_EMPTY_RESPONSE в браузере.

Еще результаты запуска какие-то недетерминированы - раньше не было коннекшна в интернет, потом тот же самый код начал работать, а сейчас валится с вышеуказанным эксепшном.

Последний эксепшн я получил в другом проекте, где код теста тот же самый, но там чуть больше зависимостей в build.gradle.

Так что все еще разбираюсь почему разные результаты на разных запусках одного и того же теста.

@ahanziuk Класс!
Ну да, у меня такая же ошибка. Как раз сейчас пишу пост об этом. :slight_smile:

Если вкратце, ошибка NoSuchMethodError: io.netty.buffer.ByteBuf.isContiguous() говорит о том, что в classpath закрались какие-то джары несовместимых версий. Выполни gradle dependencies и ищи там “netty”.

Лечится добавлением явных версий netty в build.gradle:

testRuntimeOnly("io.netty:netty-all:4.1.54.Final")
testRuntimeOnly("io.netty:netty-codec:4.1.54.Final")

@ahanziuk https://ru.selenide.org/2020/11/17/why-proxy-does-not-work-in-selenoid/

3 Симпатий

А я сейчас сравнил 2 проекта и в том, где результаты запуска теста менялись в зависимости от включенного трека на спотифае, я забыл удалить зависимость net.lightbody.bmp:browsermob-core:2.1.5, т.е там была она и com.browserup:browserup-proxy-core:2.1.1. Вот она, скорее всего, и давала конфликт зависимостей. Потом я эту депенденси удалял, но гредл мог что-то закешировать.

Сегодня ночью я добавлял io.netty:netty-codec:4.1.54.Final, не помоголо, а закинуть еще io.netty:netty-all:4.1.54.Final не пришло в голову.

Мне вся эта катавасия нужна, чтобы проверять графики и чарты, которые каждую минуту могут обновляться и иметь возможность их проверять на стабах.

Вся беда в том, что “попробовал”, “не пришло в голову” - несистемный подход.
Не надо догадываться, не должно ничего приходить в голову.
Надо почитать логи, посмотреть дерево зависимостей и чётко выяснить, где проблема.

Так netty зависимости я же тоже не просто так добавлял)) У меня на машине упоминаний зависимостей с netty более 100 (awssdk - вот этот товарищ ответственен за такое большое количество пакетов), нужно было чуть больше усидчивости, чтобы сравнить их всех и учесть, что есть некоторые версии совместимые друг с другом (например, 4.1.43 и 4.1.46) в контексте той проблемы, что у меня была.

Спасибо за статью!
Все работает только с одной зависимостью testRuntimeOnly("com.browserup:browserup-proxy-core:2.1.1"), просто не нужно было пробовать стартовать свой мок сервер, когда у селенида для этого есть обвертка.