R/Shiny的shinytest工具JS解释器不支持Promise等新特性如何解决?
问题根源
该兼容问题来自shinytest v1的默认底层依赖PhantomJS,该浏览器内核已于2018年停止维护,完全不支持ES6及以上版本的JavaScript语法,包括startsWith、Promise等常见特性,是你遇到报错的核心原因。
解决方案
方案1:迁移到shinytest2(最推荐)
shinytest官方二代版本已废弃PhantomJS,改用基于Chromium的chromote作为默认后端,完整支持所有现代JS特性,仅需少量修改即可适配原有测试逻辑:
- 安装依赖:执行
renv::install("shinytest2") - 改造后测试代码示例:
library(shiny) library(shinytest2) ui <- fluidPage( titlePanel("Hello Shiny!"), sidebarLayout( sidebarPanel(), mainPanel() ) ) server <- function(input, output) {} app <- shinyApp(ui = ui, server = server) # 替换原有ShinyDriver为AppDriver testapp <- AppDriver$new(app, debug = "all") testapp$run_js("console.log('Hello')") print(testapp$get_logs("browser")) testapp$run_js("console.log('a'.startsWith('b'))") print(testapp$get_logs("browser")) testapp$run_js("console.log(Promise)") print(testapp$get_logs("browser"))
方案2:为旧版shinytest注入JS polyfill
如果暂时无法迁移到shinytest2,可以手动注入ES6+特性的兼容polyfill补全缺失能力:
方式A:在应用UI中引入本地polyfill
提前将core-js等兼容包下载到应用的www目录,在UI代码中引入,页面加载时自动补全特性:
ui <- fluidPage( # 引入本地存储的polyfill文件 tags$script(src = "core-js-minified.js"), titlePanel("Hello Shiny!"), sidebarLayout( sidebarPanel(), mainPanel() ) )
方式B:执行自定义JS前动态注入polyfill
无需修改应用代码,在测试脚本执行业务JS前先运行对应特性的兼容代码:
# 注入startsWith方法兼容代码 testapp$executeScript(" if (!String.prototype.startsWith) { String.prototype.startsWith = function(search, pos) { pos = !pos || pos < 0 ? 0 : +pos; return this.substring(pos, pos + search.length) === search; }; } ") # 注入Promise兼容代码(可直接使用公开的Promise polyfill精简代码) testapp$executeScript("/* 粘贴Promise兼容实现代码 */")
内容的提问来源于stack exchange,提问作者Allan Karlson
相关产品推荐
相关产品推荐

