Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Idea: Handle Dusk requests inside test process #996

Closed
inxilpro opened this issue Sep 2, 2022 · 5 comments
Closed

Feature Idea: Handle Dusk requests inside test process #996

inxilpro opened this issue Sep 2, 2022 · 5 comments
Assignees

Comments

@inxilpro
Copy link
Contributor

inxilpro commented Sep 2, 2022

Right now one of the trickiest parts of using Dusk, in my experience, is the fact that your tests run in one process and the web server runs in a separate process. This means that Dusk tests can't take advantage of things like RefreshDatabase, and you can't directly manipulate the application state from within your test.

I have an idea that could potentially remove that constraint by proxying incoming Dusk requests back to the process running the PHPUnit tests. Here's how it would work:

  • When Dusk starts, it would start a TCP server (using PHP's native socket_* methods)
  • It would then spawn a separate PHP process similar to how php artisan serve works, using a special dusk-proxy.php router
  • Instead of loading our Laravel app, dusk-proxy.php would:
    • create a TCP client
    • connect to the Dusk TCP server
    • forward the incoming request data
    • wait for a response from the TCP server and return that response locally
    • close the TCP connection and end the request
  • Dusk could then listen to the incoming requests over the TCP connection and forward them on to the current HTTP Kernel (similar to how TestCase::call works)

A very thin transport protocol would be necessary to send the right request/response data over the TCP connection. Once that was in place, an API would be necessary to tell Dusk when to read the TCP buffer (so that it doesn't just block test execution). I think that second part could mostly (or maybe entirely) be transparent, since calls like $browser->visit('/login') implicitly signal when Dusk would need to fetch the request.

All-in-all, this would be a huge undertaking and would be a pretty big breaking change. It may make more sense to release something like this as a brand new package. It may be that you've explored this technique and found a major issue with it. Either way, before I explore it too much more, I'd love some feedback on the concept.

@inxilpro
Copy link
Contributor Author

inxilpro commented Sep 2, 2022

Two follow-up thoughts:

  • I tried a basic implementation using STDIN and STDOUT but it looks like php -S does not forward STDIN to the router so there's no way to get feedback from the parent process (am I wrong? anyone know a workaround?)
  • It could be better to use some sort of filesystem-based messaging system (like just writing to a storage/framework/dusk/{uuid}.response file or something), since dealing with TCP sockets may cause more problems than it's worth (and will definitely lead to timeout/blocking issues if not done correctly)

@driesvints
Copy link
Member

Ping @crynobone. Do you might have any thoughts here?

@crynobone
Copy link
Member

It may make more sense to release something like this as a brand new package.

I personally feel you can start this as a 3rd party package and have it proven first. Dusk currently is slow but it should work well with php artisan serve or php artisan octane:start.

@driesvints
Copy link
Member

Hi there @inxilpro. Thanks for your request but we're going to pass on this and keep things simple for Dusk. Sorry

@inxilpro
Copy link
Contributor Author

If anyone stumbles upon this and is interested, I've got a working proof of concept that's pretty darn cool. Take a look at:

https://twitter.com/inxilpro/status/1569371159333838854

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants