Closed lvmajor closed 4 years ago
If the host won't be able to write files, You might need to manually install drivers (and maybe browsers). You could add this to your deploy process:
dotnet tool install playwright-sharp-tool -g
playwright-sharp install-browsers
cd C:\inetpub\wwwroot<app-name>\playwright-sharp-drivers
playwright-sharp install-driver
Hmmmm.... I did copy the drivers manually but still get the error.... I also tried to switch back to dev environment and run the app from console and this worked after copying the drivers manually, but when switching back to staging or production flag, not working anymore...
I see 2 potential solutions:
You could also install the drivers in a path that you now the host user will be able to execute apps, and pass that path to CreateAsync
That's an idea :)
Meanwhile I have created the folder manually and gave the permissions to the user running the app (same user as in IIS) and now it passed the first error. Now I get a new one saying:
"Failed to launch chromium because executable doesn't exist at C:\Windows\system32\config\systemprofile\AppData\Local\ms-playwright\chromium-799411\chrome-win\chrome.exe Try re-installing playwright with "npm install playwright"
If I use the dotnet tool, where does it install the drivers (I will look into the code, but if you know it by heart, I'll take it from you ahah)
Edit: Seems like I cannot use the dotnet tool as I don't have the SDK on the staging/production environment. Now if I install the drivers and browser manually, is there not a chance that it will stop working over time as Playwright will expect a different version?
install-driver
will use the current directory unless --path
is passed.
"Failed to launch chromium because executable doesn't exist at C:\Windows\system32\config\systemprofile\AppData\Local\ms-playwright\chromium-799411\chrome-win\chrome.exe Try re-installing playwright with "npm install playwright"
Did you run playwright-sharp install-browsers
?
^Yeah ok. Now for the browser instance, it expects it to be in AppData\Local\ms-playwright\chromium-<version>\chrome-win\chrome.exe
, what is supposed to install this? I guess it is done via the Playwright.CreateAsync
call?
As now that I have manually installed the drivers, it is the missing browser that causes trouble as mentioned above... this seems a little bit fragile at the moment :)
Did you run
playwright-sharp install-browsers
?
No I did not as I can't install the dotnet tool on the production server as I only have the runtime, not the SDK. But, in my actual code, I do call both
await Playwright.InstallAsync();
using var playwright = await Playwright.CreateAsync();
So InstallAsync
should work.
If you manually copy the driver somewhere the host can execute it, you can pass that driver path to CreateAsync
.
I did copy the driver somewhere the host can execute it as I do not get the error anymore (I changed permissions and now that works), but it doesn't seem to install the browser as expected... for which I would expect an error if there's a permission problem as was the case for the driver install, would you expect it too?
What do you mean with it doesn't seem to install the browser as expected
?
What I mean is that when calling the functions above (InstallAsync
and CreateAsync
), I would expect it to install the browser it needs in C:\Windows\system32\config\systemprofile\AppData\Local\ms-playwright\chromium-799411\chrome-win\chrome.exe
but that folder does not exist at all after running those 2 lines.
In fact, the AppData\Local\ exists, but no ms-playwright folder is being created at all. Sorry if that was not clear...
@lvmajor one thing you could try is running your driver manually with the --install
flag :)
Okay I will try that right away, do you have the full command to pass? Or is it simply run the exe with this flag?
cd C:\inetpub\wwwroot<app-name>\playwright-sharp-drivers\0.142.2.0
playwright-driver-win.exe --install
I did run it, and it did execute (though I did not see any log), but there is still no ms-playwright
folder to be found...
I bet you are running under another user which is not systemprofile
.
Can we try setting an environment variable before?
set PLAYWRIGHT_BROWSERS_PATH "C:\Windows\system32\config\systemprofile\AppData\Local\ms-playwright"
Sure let me try that, I'll report asap
Sadly still nothing appears under the expected path... I included screenshots of the commands performed in the folder where the driver is, and the path where we would expect to see a ms-playwright
folder.
How about this in PowerShell?
$env:PLAYWRIGHT_BROWSERS_PATH="C:\Windows\system32\config\systemprofile\AppData\Local\ms-playwright"; .\playwright-driver-win.exe --install
I am currently away from my pc for about 45min, as soon as I come back I will try and report. Thanks for your help!
Okay so setting the environment variable correctly made it successfully install the browser at the expected location, so at least it's moving forward ahah.
Now for the really weird part... I still get the same error...
An unhandled exception has occurred while executing the request.
Exception:
PlaywrightSharp.PlaywrightSharpException: Failed to launch chromium because executable doesn't exist at C:\Windows\system32\config\systemprofile\AppData\Local\ms-playwright\chromium-799411\chrome-win\chrome.exe
I restarted the app in case it would help, to no avail...
I mean... I can clearly see it there where it is expected....
Okay so I updated the permissions of the folder containing the chrome.exe and now it can find it, but then I fall on a timeout error, which I'm currently trying to troubleshoot as it was not doing it in dev.
Cool. Another possibility, that could improve your deploy times, is downloading the driver and the browser in the App_Data
folder of the site. And pass those paths to the CreateAsync
function. You wouldn't need the InstallAsync
call there.
I guess this can be done via the dotnet tool (if I were to install the SDK)?
I'll keep troubleshooting to try to find the timeout error source and if I don't find it, I will try to switch to a local folder as you suggested and see if that fixes it.
Couldn't find the source of the timeout error, I have no error/warning generated by my app and the only error message from Playwright Sharp is timeout exceeded....
So here I go trying the local installation ahah
If you find some stack trace, I'm here to help :)
Ok so for the local test I copied over the ms-playwright
and the playwright-sharp-drivers
folders. Also when calling CreateAsync
I specified the paths for browsersPath
and driversExecutablePath
(should I set driversLocationPath
instead?.
As of my first test, I got a permission denied error again... damnation!
Win32Exception: Access is denied.
You can pass driversLocationPath
pass the playwright-sharp-drivers
location.
That seems to be working now finally. BUT, it looks like it reverted to a previous version of the driver/browser or something else because I am having page sizing issues again like I had a couple days ago....
I will double check to ensure I have nothing in cache that could be the culprit here!
Yeah that was it, stale stylesheets on my other PC whew.
Okay now that the local version works in dev environment, I will try to update to staging and report back when done. Thanks for your help and time and sorry to keep spamming you with the problems ahah :)
Your current problem is the solution for the next folk coming here :)
I certainly hope so! I just start to wonder sometimes if it's just me that's being plain dumb as crap lol XD
You are using Playwright-Sharp, so you are not 😂
Sadly for me this error message is not really helpful ahah:
Category: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware
EventId: 1
ConnectionId: 0HM3GFKV5B4D4
RequestId: 0HM3GFKV5B4D4:00000007
RequestPath: /SampleReports/GenerateReport
SpanId: 17cf453545baba43
TraceId: 8a57251c6a60e148b6d15e3bc2b5491e
ParentId: 0000000000000000
An unhandled exception has occurred while executing the request.
Exception:
System.TimeoutException: Timeout of 30000ms exceeded
at PlaywrightSharp.Helpers.TaskHelper.WithTimeout[T](Task`1 task, TimeSpan timeout, Func`2 exceptionFactory) in /Users/neo/Documents/Coding/Personal/playwright-sharp/src/PlaywrightSharp/Helpers/TaskHelper.cs:line 139
at PlaywrightSharp.Transport.Connection.SendMessageToServerAsync[T](String guid, String method, Object args, Boolean ignoreNullValues, JsonSerializerOptions options, Boolean treatErrorPropertyAsError) in /Users/neo/Documents/Coding/Personal/playwright-sharp/src/PlaywrightSharp/Transport/Connection.cs:line 224
at PlaywrightSharp.Frame.WaitForSelectorAsync(Boolean isPageCall, String selector, Nullable`1 state, Nullable`1 timeout) in /Users/neo/Documents/Coding/Personal/playwright-sharp/src/PlaywrightSharp/Frame.cs:line 576
IIRC there was no way yet to pass the debug log from Playwright to Playwright-Sharp correct?
@lvmajor we introduced that option :) https://playwrightsharp.dev/examples/Playwright.Logger.html
Oh sweet let me activate it to see if I can dig a little bit more and find what the heck is happening in staging/prod that doesn't in my dev environment!
Thanks for the pointer! (I should have checked the documentation even if it's new, but I remembered you said it was not possible a couple days ago so I didn't think it would be by now ahah)
I think I found the culprit, I was using a WaitForSelector
call which used a selector that is not always present on page depending on some conditions.
To make a long explanation "relatively shorter":
WaitForSelector
which is waiting on an element with a css class that is given to it once all graphics have completed their initialization.Now you will surely wonder why I would explain that to you even if this has strictly nothing to do with PlaywrightSharp, so let me explain why I did describe my problem.
I would want to know if there is a way to use WaitForSelector
, but instead of having a hard timeout in which an exception is thrown, it would be really nice if we could have an option to set a "soft timeout" which would simply block the generation process while waiting for the selector and after the specified timeout, simply go on and perform the conversion even if the condition was not respected.
I think that could add a certain flexibility to the usage of the WaitForSelector
(and other waiting options) for cases when the desired outcome would be, simply said "Wait until condition
@lvmajor let me share that with the team. That could also be wrapped on the .NET side. You could also write an extension method:
public static IElementHandle TryWaitForSelectorAsync(this IPage page, string selector)
{
try
{
return page.WaitForSelectorAsync(selector);
}
catch(TimeoutExeption ex)
{
return null;
}
}
Yes the local wrapper is a great idea, that's exactly what I was just thinking about! (I was just wondering if it was a good idea as I remember some people advising against using try/catch as much as possible... but in this case I think it wouldn't hurt ahah. :)
Also, as you have proposed this solution too, I think it's safe to assume it's not a bad idea after all ahah (at least temporarily until it gets implemented officially, if ever obviously 🤣 )
I remember some people advising against using try/catch as much as possible
That's a good advice :p that's why I want to check this upstream.
Excellent, keep me updated if possible! I would greatly appreciate it 😉
Do you want to close this issue, and open a new one with that feature request?
Sure I can do that (I will try to open the feature request within an hour or so as right now I got to implement a temporary fix and publish in staging/production as soon as I can)
Hey there!
I just deployed the first version of my app with Playwright-Sharp to a staging environment and I had some errors when trying to generate a pdf due to unauthorized access to the filesystem.
The error happens when creating/installing the drivers I think as this is the exact message: "System.UnauthorizedAccessException: Access to the path 'C:\inetpub\wwwroot\\playwright-sharp-drivers\0.142.2.0' is denied."