Coder Social home page Coder Social logo

Compatibility with Centos 6? about dusk HOT 20 CLOSED

laravel avatar laravel commented on August 27, 2024
Compatibility with Centos 6?

from dusk.

Comments (20)

georaldc avatar georaldc commented on August 27, 2024

Another thing I noticed is dusk doesn't seem to be starting up chromedriver properly when I run ./artisan dusk. I see it running the process via ps a but I just get a "couldn't connect to host" error. If I start chromedriver-linux manually, then I get the error I see earlier (Operation timed out after 30000 milliseconds with 0 bytes received).

EDIT:
Actually, it does seem to randomly run. Either way, I still have not been able to run any test at all because of the timeout problem.

EDIT2:
Well, could never figure out how to get chromedriver to work. I did get it to work with Selenium and Firefox but the example test ($browser->visit('/')->assertSee('text')) takes 15 seconds to complete. Any reason why?

from dusk.

deleugpn avatar deleugpn commented on August 27, 2024

I'm trying on Centos 7 and facing the same problems as you. How did you run it on Firefox?

from dusk.

georaldc avatar georaldc commented on August 27, 2024

@deleugpn
Not sure about Centos 7 but to get firefox working, I installed the following via yum: java openjdk (for selenium), xvfb for headless testing (package is called xorg-x11-server-Xvfb.x86_64 on Centos 6) and the firefox browser itself. I then downloaded the selenium jar from http://selenium-release.storage.googleapis.com/index.html. All that's needed is to set the env variable DISPLAY to the same value you would use when running xvfb in the background, start up selenium, and modify your DuskTestCase file to comment out the googledriver line and to pass the right url + port to RemoteWebDriver. So something like the following:

# Set DISPLAY env variable and start xfvb and selenium
export DISPLAY=:0
Xvfb :0 -ac -screen 0 1280x720x24 &
java -jar /path/to/selenium-server-standalone.jar
// PHP. Edit DuskTestCase class driver() method
return RemoteWebDriver::create(
    'http://localhost:4444/wd/hub', DesiredCapabilities::firefox()
);

Yum gave me an old version of firefox, 45.7. If you use newer versions, I believe you would need to use geckodriver (https://github.com/mozilla/geckodriver). Just download the appropriate build and run selenium with it

java -Dwebdriver.gecko.driver=/path/to/geckodriver -jar /path/to/selenium-server-standalone.jar

Hope that helps, and hopefully it runs better for you. Selenium + firefox still takes 15+ seconds for every page load for me :(

from dusk.

deleugpn avatar deleugpn commented on August 27, 2024

I managed to run Dusk on Cent OS 7. I hope you can do the same on Cent OS 6. After installing Chromium Browser, you just need to create a separate user (NOT ROOT), turn on the Xvfb and run dusk as not root as well. If you want to run it specifically as root, you can try to run it with the arguments --no-sandbox.

login as: dusk
[email protected]'s password:
Last login: Mon Mar  6 13:07:30 2017 from 192.168.56.1
[dusk@php7 ~]$ Xvfb -ac :0 -screen 0 1280x1024x16 &
[1] 2177
[dusk@php7 ~]$ cd /var/www/solucoesideais/laravel-dusk/
[dusk@php7 laravel-dusk]$ php artisan serve --host=127.0.0.1 --port=8000 --env=dusk.environment &
[2] 2186
[dusk@php7 laravel-dusk]$ Laravel development server started: <http://127.0.0.1:8000>

[dusk@php7 laravel-dusk]$ php artisan dusk
PHPUnit 5.7.15 by Sebastian Bergmann and contributors.

[Mon Mar  6 13:23:28 2017] 127.0.0.1:59146 [200]: /favicon.ico
.                                                                   1 / 1 (100%)

Time: 3.7 seconds, Memory: 10.00MB

OK (1 test, 1 assertion)
[dusk@php7 laravel-dusk]$

from dusk.

georaldc avatar georaldc commented on August 27, 2024

@deleugpn I tried updating my docker environment to Centos 7 and while that helped make running chromedriver much more easier, I still end up with similar "Operation timed out after 30001 milliseconds with 0 out of -1 bytes received" errors

from dusk.

deleugpn avatar deleugpn commented on August 27, 2024

Check file permission, try to run the driver manually (confirm it's listening to port 9515) and check if you have Xvfb set.

from dusk.

georaldc avatar georaldc commented on August 27, 2024

So I've tried the following:

  1. Created a new user called "foobar"
  2. Switched to foobar. Set $DISPLAY to :0. Started Xvfb
  3. Ran ./artisan dusk as foobar

ps shows the following processes running

php ./artisan dusk
php vendor/bin/phpunit -c /var/www/html/BhamDashboard/phpunit.dusk.xml
/path/to/vendor/laravel/dusk/bin/chromedriver-linux
[chrome] <defunct>
[chrome] <defunct>

Not sure why chrome shows up twice but I can confirm that chromedriver is running under port 9515 since running a second instance manually would give me the "address already in use" message. Tests I have take 30 or more seconds each, timing out at the end

EDIT:
Forgot to add but I also have ./artisan serve running and my config APP_URL is set to http://localhost:8000

from dusk.

deleugpn avatar deleugpn commented on August 27, 2024

Set it up in a way that only one test will be executed (to speed things up). You can take advantage of --group=fail for this. Then, go to Laravel/Dusk/TestCase.php, line 207 and reduce retry from 5 to 2 times, also to speed things up. Lastly, go to your DuskTestCase.php and add more timeout:

        return RemoteWebDriver::create(
            'http://localhost:9515', DesiredCapabilities::chrome(), 150000, 150000
        );

This will probably be enough time for Chrome Driver to actually tell you what is wrong.

You can also try removing the retry completely for the purpose of this testing. The goal is to not rely on Facebook Webdriver's timeout settings. You want to let the application run until Chrome Driver gives you an error.

from dusk.

georaldc avatar georaldc commented on August 27, 2024

Interesting, I increased the timeout with your suggestion and I do see a clearer error: Chrome failed to start: crashed. I wonder if chromedriver was trying to start chrome from the wrong location? Need to look at some logs...

from dusk.

deleugpn avatar deleugpn commented on August 27, 2024

I plan on writing a Medium post about this, but to sum it all up: Chrome Driver implements a HTTP protocol that Facebook Webdriver uses to manipulate the browser. As any HTTP Request, Facebook Webdriver relies on 30 seconds timeout. If you forget about Dusk completely, you can start chromedriver manually and then call it yourself through Postman (map your host machine with your guest machine through a access port). Then you can call something like GET 192.168.56.101:9515/sessions and chrome should reply with the sessions available or empty array. If you send a POST to /sessions, it will open a new tab for you and give you it's ID.

Basically this was the way that I used to debug everything. Do straight with POSTMAN + Chrome Driver with output logs and you'll be able to see what Chrome Driver is telling you. I remember going through the crash situation, I think it was indeed chrome installation. I think I ended up making a symbolic link for chrome on /usr/bin or something so Chrome Driver could see it.

After you learn how to manipulate Chrome Driver yourself, it's a piece of cake to understand how Dusk interacts with Facebook Webdriver to create an easy API for us to test the application.

from dusk.

georaldc avatar georaldc commented on August 27, 2024

So it seems that chromedriver, according to it's logfile, gets stuck trying to do a DevTools request to http://localhost:some-port-number/json/version over and over again, failing everytime until the timeout is reached. It's also calling the correct chrome binary, but chrome complains with the following error "Failed to move to new namespace: PID namespaces supported, Network namespace supported". If I try supplying the no-sandbox argument to Chrome, then it looks like Chrome starts to work with the following warnings:

Xlib: extension "RANDR" missing on display ":0"
NaCl helper process running without a sandbox!
Most likely you need to configure your SUID sandbox correctly

I read that these warnings can be ignored, but chromedriver still hangs repeatedly trying to do that DevTools request earlier.

from dusk.

georaldc avatar georaldc commented on August 27, 2024

I finally got it to work. For some reason, it seems like some fonts were needed so I had to run the following:

yum -y install liberation-mono-fonts liberation-narrow-fonts liberation-sans-fonts liberation-serif-fonts

Got the tip from here https://www.centos.org/forums/viewtopic.php?f=48&t=60908&start=10#p257122

I also need to use the --no-sandbox option. I could not get it to work without that option, even with a non-root user.

from dusk.

deleugpn avatar deleugpn commented on August 27, 2024

Did you install Chromium Browser instead of actual Google Chrome? Chromium Browser is supported by Google for RedHat while Google Chrome is a 3rd-party adaptation.

from dusk.

georaldc avatar georaldc commented on August 27, 2024

I installed google-chrome first (used the same script I previously needed to get chrome on Centos 6, https://chrome.richardlloyd.org.uk/). I then tried to install Chromium to see if I run into problems running it and got the same font errors as described in the centos.org link/post I put up. So I installed those fonts and now I'm able to get chromedriver to work with google-chrome.

So no, I'm not using Chromium Browser at the moment.

from dusk.

deleugpn avatar deleugpn commented on August 27, 2024

I think I was only able to run Chromium without the sandbox flag, not Chrome.

from dusk.

georaldc avatar georaldc commented on August 27, 2024

@deleugpn I'm sorry if this isn't related to the issue, but I have a question for you. I believe you use Dusk with the internal PHP webserver correct? If so, would you happen to know of any workarounds when needing to make requests to yourself (like doing a CURL request to yourself from an ajax call)? The reason I ask is I know that mocking objects is a problem right now with Dusk and I figured I would just create a test API URL to points to myself (routes become available only during testing) to mock the responses for an external API my APP uses. Problem is I just realized that I would end up with a deadlock of sorts since the internal PHP webserver cannot handle more than 1 request at a time.

I've actually given up on trying to get Dusk to work on my dev environment. While I may have gotten Chrome to somewhat work, the actual testing part just executes too slow. This is probably related to Docker's slowness when working with shared files on a Windows host. So now, I'm just trying to run Dusk through my host machine instead and was hoping that I could just rely on PHP's internal server, instead of having to install a web server too on my host machine

from dusk.

deleugpn avatar deleugpn commented on August 27, 2024

you use Dusk with the internal PHP webserver correct

Yes. With php artisan serve --env=dusk.local &.

Ajax I know you won't have problems. I have a test that clicks on a button and waits for an ajax response and then asserts for database changes.

    /**
     * @test
     */
    public function it_should_rate_finished_ticket() {
        $user = factory(User::class, 'customer')->create();
        $ticket = factory(Ticket::class)->create(['status_id' => 4, 'user_id' => $user->id]);

        $this->browse(function (Browser $browser) use ($user, $ticket) {
            $rate = rand(1, 5);
            $browser->loginAs($user, 'customer')
                ->visit(new TicketsPage)
                ->click('#label-rating-1-item-' . $rate, $rate)
                ->assertRadioSelected('@rating-' . $rate, $rate)
                ->waitFor('@success-message');

            // Reload and Assert
            $ticket = $ticket->find($ticket->id);
            $this->assertTrue($ticket->rate == $rate);
        });
    }

The reason this works is because Dusk (through Facebook Web Driver) makes a HTTP request to Chrome Driver for a new Chrome Session. Once that is done we're inside the testable callback. When visiting a page, Chrome Driver will instruct the browser to load the page and once it's fully loaded, PHP Internal Server will rest (it's job is done). You cannot make an ajax call from the page until the page is fully loaded, hence you cannot deadlock it by making two calls. Chrome NEEDS to wait the page to be done so it can act and your action will be performed after the server is free to take your ajax request.

Now, when making a request from your controller, you might be right because Chrome is waiting for the PHP Server to reply with the page, but PHP Server would be waiting itself to reply an internal request, leading to deadlock.

from dusk.

georaldc avatar georaldc commented on August 27, 2024

So I guess there is no sane way to fake responses for server code that interfaces with an external API through the internal PHP web server, other than running things through an actual web server?

Would have been nice if mocking were possible, since then I would have just simply created an object that returned fixed responses instead of going through the wire.

from dusk.

deleugpn avatar deleugpn commented on August 27, 2024

I have been bashing my head on mocking. My first dead end was trying to serialize a closure and then executing it from the PHP process that is invoked by Chrome. Now I'm trying with a static class and although I managed to serialize/unserialize it, calling Mail::fake() and Mail::shouldReceive('something') doesn't seem to be enough for the test to fail if I don't call Mail::something();.

from dusk.

georaldc avatar georaldc commented on August 27, 2024

That doesn't sound fun. I might just put environment checks inside my AppServiceProvider class and load mocked classes when under testing.

I'm closing this issue since I sort of found the answer to the cause of my main issue in the first place (getting chrome to run)

from dusk.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.