positron icon indicating copy to clipboard operation
positron copied to clipboard

`shiny::paneViewer()` sends Shiny app to Viewer on Mac but NOT on Windows

Open strengejacke opened this issue 1 year ago • 11 comments

System details:

Positron and OS details:

Positron Version: 2024.09.0 (system setup) build 77 Code - OSS Version: 1.93.0 Commit: 9b6f7c066546a4c7f104368fc769fb3768b08bfd Date: 2024-09-23T02:44:07.418Z Electron: 30.4.0 Chromium: 124.0.6367.243 Node.js: 20.15.1 V8: 12.4.254.20-electron.0 OS: Windows_NT x64 10.0.22631

Interpreter details:

R 4.4.1

Describe the issue:

When I test graphical outputs from ggplot, using testthat and vdiffr, and a snapshot has changed, I cannot review the old and new snapshot. The console says that the shiny-app that allows you to toggle between old/new snapshot is launched, but nothing happens.

strengejacke avatar Sep 29 '24 12:09 strengejacke

@strengejacke

Thanks for flagging this! We appreciate your help improving Positron. Do you have a reprex for this? I'm trying to create one and using shinytest can't even launch an app properly to record a test. It times out waiting on the app to load but it does seem to be running, just not launched into the Viewer or a browser.

timtmok avatar Sep 30 '24 16:09 timtmok

Yes, that's exactly what happens for me, too. In RStudio or VSCode, it works fine.

strengejacke avatar Sep 30 '24 16:09 strengejacke

It sounds like Positron is missing the event to open the app in the Viewer. I'll mark this for further triage.

timtmok avatar Oct 02 '24 13:10 timtmok

I was taking a look at this and don't observe a problem myself:

Image

This may be a too-obvious question, but do you have the Shiny extension installed? We do not currently bundle it, but it is needed to run Shiny apps in Positron.

juliasilge avatar Oct 07 '24 21:10 juliasilge

Hm, doesn't seem to solve the problem.

I installed this extension: https://open-vsx.org/extension/posit/shiny

This is the output from Windows

2024-10-08 08:20:01.292 [debug] User data changed
2024-10-08 08:20:01.713 [debug] User data changed
2024-10-08 08:20:15.399 [debug] suggest.durations.json {"entries":[{"providerName":"snippetCompletions","elapsedProvider":1.0999999940395355,"elapsedOverall":1.2000000178813934},{"providerName":"GitHub.vscode-pull-request-github(@)","elapsedProvider":1.241200000004028,"elapsedOverall":14.899999976158142},{"providerName":"GitHub.vscode-pull-request-github(#)","elapsedProvider":1.050199999997858,"elapsedOverall":14.900000005960464},{"providerName":"EdgardMessias.clipboard-manager()","elapsedProvider":3.511499999993248,"elapsedOverall":15.900000005960464},{"providerName":"vscode.positron-r($@:)","elapsedProvider":132.40350000000035,"elapsedOverall":192.69999998807907}],"elapsed":194.19999998807907}
2024-10-08 08:20:45.266 [debug] Comments: URIs of continue on comments to add to storage .
2024-10-08 08:21:17.730 [error] [uncaught exception in main]: Failed to open: Das System kann die angegebene Datei nicht finden. (0x2): Error: Failed to open: Das System kann die angegebene Datei nicht finden. (0x2)
2024-10-08 08:21:45.294 [debug] Comments: URIs of continue on comments to add to storage .
2024-10-08 08:21:48.223 [debug] User data changed
2024-10-08 08:22:21.147 [debug] User data changed

This is the last output in KErnel

[R]   2024-10-08T06:20:22.476408Z ERROR  Can't determine if binding is active: Can't find binding `%>%` in environment
[R]     at crates\ark\src\lsp\completions\completion_item.rs:386
[R] 

The Console output is a bit longer

2024-10-08 08:21:14.553 [info] RECV comm_msg/positron-ui-r-1-9dde2fd1/undefined from iopub: {"header":{"msg_id":"c763c60a-48f5-48b0-b4ae-b4a21446fb96","session":"907b3d88-f735-475d-83ea-1001a090ccca","username":"kernel","date":"2024-10-08T06:21:14.551502200+00:00","msg_type":"comm_msg","version":"5.3"},"parent_header":{},"metadata":{},"content":{"comm_id":"positron-ui-r-1-9dde2fd1","data":{"method":"busy","params":{"busy":false}}},"buffers":[]}
2024-10-08 08:21:14.553 [info] RECV comm_msg/positron-ui-r-1-9dde2fd1/undefined from iopub: {"header":{"msg_id":"41eadde2-b156-429f-9424-b28aab6f9c6a","session":"907b3d88-f735-475d-83ea-1001a090ccca","username":"kernel","date":"2024-10-08T06:21:14.551537600+00:00","msg_type":"comm_msg","version":"5.3"},"parent_header":{},"metadata":{},"content":{"comm_id":"positron-ui-r-1-9dde2fd1","data":{"method":"prompt_state","params":{"input_prompt":"> ","continuation_prompt":"+ "}}},"buffers":[]}
2024-10-08 08:21:14.553 [info] RECV stream from iopub: {"header":{"msg_id":"2fed3dcc-838a-4bed-a8f0-52d350417ec6","session":"907b3d88-f735-475d-83ea-1001a090ccca","username":"kernel","date":"2024-10-08T06:21:14.551560700+00:00","msg_type":"stream","version":"5.3"},"parent_header":{"msg_id":"fragment-dc588309-66b8-4501-9e79-170ecaec54e3","session":"b9fd9a5c4f3126d4019436840618176e","username":"Daniel","date":"2024-10-08T06:20:37.310Z","msg_type":"execute_request","version":"5.0"},"metadata":{},"content":{"name":"stdout","text":"── \u001b[1m\u001b[38;5;214mFailure\u001b[39m (\u001b]8;line = 17:col = 3;file://C:/Users/Daniel/Documents/GitHub/easystats/see/tests/testthat/test-plot.check_dag.R\u0007\u001b[34mtest-plot.check_dag.R:17:3\u001b[39m\u001b]8;;\u0007): `plot()` for check_dag\u001b[22m ────────────────\nSnapshot of `testcase` to 'plot.check_dag/plot-check-dag-all.svg' has changed\nRun \u001b]8;;x-r-run:testthat::snapshot_review('plot.check_dag/')\u0007testthat::snapshot_review('plot.check_dag/')\u001b]8;;\u0007 to review changes\n\u001b[1mBacktrace:\u001b[22m\n\u001b[90m    \u001b[39m▆\n\u001b[90m 1. \u001b[39m└─\u001b[1mvdiffr\u001b[22m::expect_doppelganger(title = \"plot.check_dag all\", fig = plot(dag))\u001b[90m at \u001b]8;line = 17:col = 3;file://C:\\Users\\Daniel\\Documents\\GitHub\\easystats\\see\\tests\\testthat\\test-plot.check_dag.R\u0007test-plot.check_dag.R:17:3\u001b]8;;\u0007\u001b[39m\n\u001b[90m 2. \u001b[39m  ├─\u001b[1mbase\u001b[22m::withCallingHandlers(...)\n\u001b[90m 3. \u001b[39m  └─\u001b[1mtestthat\u001b[22m::expect_snapshot_file(...)\n\n── \u001b[1m\u001b[38;5;214mFailure\u001b[39m (\u001b]8;line = 21:col = 3;file://C:/Users/Daniel/Documents/GitHub/easystats/see/tests/testthat/test-plot.check_dag.R\u0007\u001b[34mtest-plot.check_dag.R:21:3\u001b[39m\u001b]8;;\u0007): `plot()` for check_dag\u001b[22m ────────────────\nSnapshot of `testcase` to 'plot.check_dag/plot-check-dag-current.svg' has changed\nRun \u001b]8;;x-r-run:testthat::snapshot_review('plot.check_dag/')\u0007testthat::snapshot_review('plot.check_dag/')... (truncated)
2024-10-08 08:21:14.553 [info] R kernel status changed: busy => idle
2024-10-08 08:21:14.553 [info] RECV status/idle from iopub: {"header":{"msg_id":"70f50a4c-f855-4819-9e17-58b6ee5a42e9","session":"907b3d88-f735-475d-83ea-1001a090ccca","username":"kernel","date":"2024-10-08T06:21:14.551586400+00:00","msg_type":"status","version":"5.3"},"parent_header":{"msg_id":"fragment-dc588309-66b8-4501-9e79-170ecaec54e3","session":"b9fd9a5c4f3126d4019436840618176e","username":"Daniel","date":"2024-10-08T06:20:37.310Z","msg_type":"execute_request","version":"5.0"},"metadata":{},"content":{"execution_state":"idle"},"buffers":[]}
2024-10-08 08:21:15.578 [info] RECV comm_msg/positron-variables-r-0-262d07f5/undefined from iopub: {"header":{"msg_id":"5dbe8e1a-b9aa-48e2-b77d-f7f6f87ad7c6","session":"907b3d88-f735-475d-83ea-1001a090ccca","username":"kernel","date":"2024-10-08T06:21:15.577270900+00:00","msg_type":"comm_msg","version":"5.3"},"parent_header":{},"metadata":{},"content":{"comm_id":"positron-variables-r-0-262d07f5","data":{"method":"update","params":{"assigned":[{"access_key":"m_rstan","display_name":"m_rstan","display_value":"[coefficients = 4.786962273580837 0.8858718933938106 -0.7385875138620337 0.46589213208573765 0.5217750514381767 -0.2400644298242216, ses = 0.16270589623155063 0.6069632045241972 0.4929903350455528 0.5306302260317276 0.6862567274526611 0.6495318485550196, fitted.values = 4.964136652259599 4.964136652259599 4.964136652259599 4.964136652259599 4.964136652259599 5.141311030938361, linear.predictors = 4.964136652259599 4.964136652259599 4.964136652259599 4.964136652259599 4.964136652259599 5.141311030938361, residuals = 0.13586334774040054 -0.06413665225959875 -0.2641366522595989 -0.36413665225959946 0.0358633477404009 0.2586889690616392, df.residual = NA, covmat = [[0.026207146164209653 -0.08825977427670813 -0.02444762788521847 -0.023917999368286272 0.0868282907068564 0.08701003059161738]], y = 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 5.4 4.8 4.8 4.3 5.8 5.7 5.4 5.1 5.7 5.1 5.4 5.1 4.6 5.1 4.8 5 5 5.2, model = [150 rows x 3 columns] <data.frame>, data = [150 rows x 5 columns] <data.frame>, family = [family = \"gaussian\", link = \"identity\", linkfun = function (mu) , linkinv = function (eta) , variance = function (mu) , dev.resids = function (y, mu, wt) , aic = function (y, n, mu, wt, dev) , mu.eta = function (eta) , initialize = ??, validmu = function (mu) , valideta = function (eta) , dispersion = NA], offset = NULL, weights = , prior.weights = , contrasts = [Species = \"contr.treatment\"], na.action = NULL, formula = ??, terms = ??, prior.info = [prior = [dist = \"normal\", location = 0 0 0 0 0, scale = 2.5 2.5 2.5 2.5 2.5, adjusted_scale = 2.71... (truncated)
2024-10-08 08:21:17.564 [info] Sending code to R: testthat::snapshot_review('plot.check_dag/')
2024-10-08 08:21:17.564 [info] SEND execute_request to Shell: {"buffers":[],"content":{"code":"testthat::snapshot_review('plot.check_dag/')","allow_stdin":true,"silent":false,"store_history":true,"user_expressions":{},"stop_on_error":false},"header":{"msg_id":"e5747bc2-3e5a-4ea2-a07e-76c89fa44f00","msg_type":"execute_request","version":"5.0","date":"2024-10-08T06:21:17.563Z","session":"b9fd9a5c4f3126d4019436840618176e","username":"Daniel"},"metadata":{},"parent_header":{}}
2024-10-08 08:21:17.565 [info] SEND execute_request: OK
2024-10-08 08:21:17.565 [info] R kernel status changed: idle => busy
2024-10-08 08:21:17.565 [info] RECV status/busy from iopub: {"header":{"msg_id":"587b52b8-f643-4c95-885a-3e31d33b61d3","session":"907b3d88-f735-475d-83ea-1001a090ccca","username":"kernel","date":"2024-10-08T06:21:17.564636500+00:00","msg_type":"status","version":"5.3"},"parent_header":{"msg_id":"e5747bc2-3e5a-4ea2-a07e-76c89fa44f00","session":"b9fd9a5c4f3126d4019436840618176e","username":"Daniel","date":"2024-10-08T06:21:17.563Z","msg_type":"execute_request","version":"5.0"},"metadata":{},"content":{"execution_state":"busy"},"buffers":[]}
2024-10-08 08:21:17.566 [info] RECV execute_input from iopub: {"header":{"msg_id":"8c4138c5-3142-4dc0-ad5f-d3cdbb98cf79","session":"907b3d88-f735-475d-83ea-1001a090ccca","username":"kernel","date":"2024-10-08T06:21:17.565389300+00:00","msg_type":"execute_input","version":"5.3"},"parent_header":{"msg_id":"e5747bc2-3e5a-4ea2-a07e-76c89fa44f00","session":"b9fd9a5c4f3126d4019436840618176e","username":"Daniel","date":"2024-10-08T06:21:17.563Z","msg_type":"execute_request","version":"5.0"},"metadata":{},"content":{"code":"testthat::snapshot_review('plot.check_dag/')","execution_count":3},"buffers":[]}
2024-10-08 08:21:17.566 [info] RECV comm_msg/positron-ui-r-1-9dde2fd1/undefined from iopub: {"header":{"msg_id":"0d11b8d3-87e1-4dd0-913b-f32770054056","session":"907b3d88-f735-475d-83ea-1001a090ccca","username":"kernel","date":"2024-10-08T06:21:17.565869200+00:00","msg_type":"comm_msg","version":"5.3"},"parent_header":{},"metadata":{},"content":{"comm_id":"positron-ui-r-1-9dde2fd1","data":{"method":"busy","params":{"busy":true}}},"buffers":[]}
2024-10-08 08:21:17.699 [info] RECV comm_msg/positron-ui-r-1-9dde2fd1/undefined from iopub: {"header":{"msg_id":"ce0a737b-8f93-4d8b-8f3c-fcdff2cf879b","session":"907b3d88-f735-475d-83ea-1001a090ccca","username":"kernel","date":"2024-10-08T06:21:17.698997800+00:00","msg_type":"comm_msg","version":"5.3"},"parent_header":{},"metadata":{},"content":{"comm_id":"positron-ui-r-1-9dde2fd1","data":{"method":"show_url","params":{"url":"C:\\Users\\Daniel\\Documents\\GitHub\\easystats\\see\\http:\\127.0.0.1:4525"}}},"buffers":[]}
2024-10-08 08:21:17.733 [info] RECV stream from iopub: {"header":{"msg_id":"8aab9c64-56e2-4a03-98f3-07fad3bedf56","session":"907b3d88-f735-475d-83ea-1001a090ccca","username":"kernel","date":"2024-10-08T06:21:17.732985100+00:00","msg_type":"stream","version":"5.3"},"parent_header":{"msg_id":"e5747bc2-3e5a-4ea2-a07e-76c89fa44f00","session":"b9fd9a5c4f3126d4019436840618176e","username":"Daniel","date":"2024-10-08T06:21:17.563Z","msg_type":"execute_request","version":"5.0"},"metadata":{},"content":{"name":"stdout","text":"Starting Shiny app for snapshot review\n\u001b[34mℹ\u001b[39m Use Ctrl + C to quit\nLoading required package: shiny\n"},"buffers":[]}

Meanwhile, I updated to the latest Positron:

Positron Version: 2024.10.0 (system setup) build 13
Code - OSS Version: 1.93.0
Commit: 34b5c57cf211bcaf1bc48f75a8cd8d0b4378e5f5
Date: 2024-10-03T16:22:24.120Z
Electron: 30.4.0
Chromium: 124.0.6367.243
Node.js: 20.15.1
V8: 12.4.254.20-electron.0
OS: Windows_NT x64 10.0.22631

strengejacke avatar Oct 08 '24 06:10 strengejacke

Hmmm, that sounds a bit mysterious.

  • Can you run any Shiny apps at all? For example, shiny::runExample("04_mpg")?
  • Can you run a basic example from diffviewer, like this?
library(diffviewer)
path1 <- tempfile()
path2 <- tempfile()
writeLines(letters, path1)
writeLines(letters[-13], path2)
visual_diff(path1, path2)
  • Is this a public R package that I would be able to clone myself to check out?

juliasilge avatar Oct 08 '24 16:10 juliasilge

Hmmm, that sounds a bit mysterious.

  • Can you run any Shiny apps at all? For example, shiny::runExample("04_mpg")?

That works for me!

  • Can you run a basic example from diffviewer, like this?

library(diffviewer) path1 <- tempfile() path2 <- tempfile() writeLines(letters, path1) writeLines(letters[-13], path2) visual_diff(path1, path2)

That doesn't do anything.

  • Is this a public R package that I would be able to clone myself to check out?

Sure, it's the see package (https://github.com/easystats/see). I was running this test: https://github.com/easystats/see/blob/main/tests/testthat/test-plot.check_dag.R Simply change one of the values in the coords argument, which should modify the plot and thus fail (to call the shiny-app for debugging).

Just let me know if I can help with specific outputs in Positron.

strengejacke avatar Oct 09 '24 06:10 strengejacke

@strengejacke Can you try one more time with the latest release that fixed the problems with HTML in the Viewer on Windows? The diffviewer package generates HTML widgets and I suspect they may have been broken on Windows for the same reason as https://github.com/posit-dev/positron/issues/4940.

juliasilge avatar Oct 09 '24 20:10 juliasilge

Using this version now:

Positron Version: 2024.10.0 (system setup) build 14
Code - OSS Version: 1.93.0
Commit: 901ab5d11d694212d32e53b97f771c5d601e428e
Date: 2024-10-09T15:24:43.348Z
Electron: 30.4.0
Chromium: 124.0.6367.243
Node.js: 20.15.1
V8: 12.4.254.20-electron.0
OS: Windows_NT x64 10.0.22631

Now, the first two examples mentioned here work, but testthat::snapshot_review('plot.check_dag/') still does nothing. There's the red square in the top right of the console, indicating something is busy, but nothing appears on the Viewer pane nor elsewhere. I can use ctrl+c to stop the shiny-app.

strengejacke avatar Oct 09 '24 21:10 strengejacke

Thank you so much! I found the problem; shiny::paneViewer() works in Positron on Mac but not on Windows.

Reprex is here (works on MacOS, does not on Windows):

library(shiny)
runApp(list(
  ui = bootstrapPage(
    numericInput('n', 'Number of obs', 100),
    plotOutput('plot')
  ),
  server = function(input, output) {
    output$plot <- renderPlot({ hist(runif(input$n)) })
  }),
  launch.browser = shiny::paneViewer()
)

juliasilge avatar Oct 09 '24 21:10 juliasilge

Here is what Shiny is doing in this situation:

paneViewer <- function(minHeight = NULL) {
  viewer <- getOption("viewer")
  if (is.null(viewer)) {
    utils::browseURL
  } else {
    function(url) {
      viewer(url, minHeight)
    }
  }
}

juliasilge avatar Oct 09 '24 21:10 juliasilge

+1 for the fix request

kalimu avatar Oct 22 '24 10:10 kalimu

This is quite annoying for package development on Windows. testthat::snapshot_review() is quite useful, and currently I need to open the project also on RStudio IDE to make it work.

FWIW the getOption('viewer') I see on Windows inside Positron is the following

> getOption("viewer")
function(url, height = NULL, ...) {
    # Validate the URL argument.
    if (!is.character(url) || (length(url) != 1))
        stop("url must be a single element character vector.")

    # Normalize paths for comparison. This is necessary because on e.g. macOS,
    # the `tempdir()` may contain `//` or other non-standard path separators.
    normalizedPath <- normalizePath(url, mustWork = FALSE)
    normalizedTempdir <- normalizePath(tempdir(), mustWork = FALSE)

    # Validate the height argument.
    height <- .ps.validate.viewer.height(height)

    # Is the URL a temporary file?
    if (startsWith(normalizedPath, normalizedTempdir)) {
        # Derive a title for the viewer from the path.
        title <- .ps.viewer.title(normalizedPath)

        # If so, open it in the HTML viewer.
        .ps.Call("ps_html_viewer", normalizedPath, title, height, FALSE)
    } else {
        # If not, open it in the system browser.
        utils::browseURL(normalizedPath, ...)
    }
}
<environment: 0x0000026142142248>

cderv avatar May 05 '25 15:05 cderv

The problem is with this line in ark https://github.com/posit-dev/ark/blob/40908a3b2ba4c54bba05940ffd536444abf598a0/crates/ark/src/modules/positron/viewer.R#L15

    normalizedPath <- normalizePath(url, mustWork = FALSE)

In case of example at https://github.com/posit-dev/positron/issues/4843#issuecomment-2403487936, we have

> url
[1] "http://127.0.0.1:7305"

But on windows, you can't apply normalizePath on a URL. THis is what we get

> normalizedTempdir <- normalizePath(tempdir(), mustWork = FALSE)
> normalizedPath
[1] "c:\\Users\\chris\\Documents\\DEV_R\\quarto-r\\http:\\127.0.0.1:7305"

And this is the path used with utils::browseURL()

    } else {
        # If not, open it in the system browser.
        utils::browseURL(normalizedPath, ...)
    }

from https://github.com/posit-dev/ark/blob/40908a3b2ba4c54bba05940ffd536444abf598a0/crates/ark/src/modules/positron/viewer.R#L28-L31

This is windows only problem with normalizePath

On linux this does not modify it

> normalizePath("http://127.0.0.1:7305", mustWork=FALSE)
[1] "http://127.0.0.1:7305"

So this is an issue with ark. Reprex could be

# Run a server from R for the directory
> servr::httd()
To stop the server, run servr::daemon_stop(1) or restart your R session
Serving the directory C:\Users\chris\Documents\DEV_R\quarto-r at http://127.0.0.1:4321

# Set up some trace to see the input
> trace(utils::browseURL, 
      tracer = quote({
        cat(format(Sys.time()), "| browseURL called with URL:", url, "\n")
      }),
      print = FALSE)

# Use viewer option from ark https://github.com/posit-dev/ark/blob/main/crates/ark/src/modules/positron/viewer.R
> getOption("viewer")("http://127.0.0.1:4321")
2025-05-05 18:21:57 | browseURL called with URL: c:\Users\chris\Documents\DEV_R\quarto-r\http:\127.0.0.1:4321 

The url used with utils::browseURL is not valid.

Hope it helps


EDIT: I took the liberty to open in ark as I believe this is where it should be solved.

cderv avatar May 05 '25 16:05 cderv

Verified Fixed

Positron Version(s) : 2025.07.0-49 OS Version(s) : Windows 11

Test scenario(s)

Apps now launch in viewer as expected.

Example:

library(diffviewer)
path1 <- tempfile()
path2 <- tempfile()
writeLines(letters, path1)
writeLines(letters[-13], path2)
visual_diff(path1, path2)

jonvanausdeln avatar Jun 05 '25 15:06 jonvanausdeln