-
Notifications
You must be signed in to change notification settings - Fork 23
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
added guided tour #164
added guided tour #164
Conversation
Closes #150 TDH: this comment does not work because the "Closes" comments must be in the first comment of the PR |
inst/htmljs/animint.js
Outdated
element: "#" + id, | ||
popover: { | ||
title: geom.charAt(0).toUpperCase() + geom.slice(1), | ||
description: `${helpText} Data are shown for the current selection of: ${showSelected}. Click to change selection of: ${clickSelects}.` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks like a good first step thanks!
when showSelected is an array ['var1','var2']
, does this work?
also it could be missing or empty array []
(same for clickSelects, and help)
so in that case we would want to omit each missing part altogether.
inst/htmljs/animint.js
Outdated
@@ -185,6 +185,24 @@ var animint = function (to_select, json_file) { | |||
|
|||
var add_geom = function (g_name, g_info) { | |||
// Determine if data will be an object or an array. | |||
// added geom properties in steps array | |||
var geom = g_info.geom; | |||
var id = "plot_" + geom + "Plot"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is good! what is unexpected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Geom2_vline_vlinePlot please
- please change "Geom2_vline_vlinePlot" to the value of
g_info.classed
- remove "Data are shown for the current selection of ." no text like this should be shown if there are no showSelected variables.
- remove "Click to change selection of: ." no text like this should be shown if there is no clickSelects variable.
inst/htmljs/index.html
Outdated
@@ -12,6 +12,8 @@ | |||
<script type="text/javascript" src="vendor/jquery-1.11.3.min.js"></script> | |||
<script type="text/javascript" src="vendor/selectize.min.js"></script> | |||
<link rel="stylesheet" type="text/css" href="vendor/selectize.css" /> | |||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/driver.js.iife.js"></script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you please copy these to inst/htmljs/vendor? and then use relative links here? (as with jquery etc above)
this approach is more stable (all files hosted on same server, don't need to rely on external cdn)
inst/htmljs/animint.js
Outdated
|
||
element.append("button") | ||
.text("Start Tour") | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please undo addition of empty line in the middle of statements like this
inst/htmljs/animint.js
Outdated
.text("Start Tour") | ||
|
||
.on("click", function() { | ||
startTour(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if this is the only place that startTour is called, I think it not worth adding the startTour function. can you please move the contents of startTour inside this anonymous function?
looks like a good start, thanks very much! |
updated html to use relative paths
@tdhock thanks now I can render the UI in the browser. But it takes almost 10 seconds to load and during that time this error comes Error: Chromote: timed out waiting for response to command Page.navigate. I tried using Sys.sleep() but it didn't work. I might be missing something, the code: library("chromote")
library("httpuv")
click_button <- function(session, selector) {
result <- session$Runtime$evaluate(sprintf(
"const button = document.querySelector('%s');
if (button) { button.click(); return 'Clicked'; } else { return 'Not Found'; }", selector
))
return(result$result$value)
}
current_dir <- getwd()
folder_name <- grep("^animint_vline", list.files(current_dir), value = TRUE)
if (length(folder_name) > 0) {
folder_path <- file.path(current_dir, folder_name[1])
if (dir.exists(folder_path)) {
server <- startServer("127.0.0.1", 4848, list(
call = function(req) {
path <- sub("^/", "", req$PATH_INFO)
file_path <- file.path(folder_path, path)
if (file.exists(file_path)) {
return(list(status = 200L, headers = list("Content-Type" = mime::guess_type(file_path)), body = readBin(file_path, "raw", file.info(file_path)$size)))
} else {
return(list(status = 404L, headers = list("Content-Type" = "text/plain"), body = "File not found"))
}
}
))
Sys.sleep(10)
url <- "http://127.0.0.1:4848/index.html"
b <- ChromoteSession$new()
b$view()
tryCatch({
b$Page$navigate(url)
b$Page$loadEventFired(wait_ = TRUE)
start_result <- click_button(b, "button#start-tour")
if (start_result == "Clicked") {
repeat {
next_result <- click_button(b, "button#next")
if (next_result != "Clicked") break
}
}
}, error = function(e) {
cat("Error:", e$message, "\n")
})
# stopServer(server)
} else {
cat("Error: Folder path does not exist.\n")
}
} else {
cat("Error: No folder starting with 'animint_vline' found.\n")
} |
@tdhock I read testing documentation when I run tests_run() command then animint library is installed in the testthat folder and visualization run in browser and I can test those element but here I made changes in animint library and the animint library is reinstall in the testthat folder everytime I run tests_run() overwriting my changes so how do I test those guided tour features I was trying to test the guided tour features using the above method, but facing timeout error may be I am missing something It would be helpful if you could guide video of basic testing https://youtu.be/ch0tRSHUlxk |
I don't hear any sound in your video. Can you talk about what you are doing next time? and what you observe? if the code is working as intended?
I believe you mean the animint.js code? that comes from animint2/inst/htmljs/animint.js so maybe you need to add your code there? |
also in your video I saw a typo "counry" did you mean "country" ? |
In this issue, my main task was to add a guided tour feature, so I made changes in the animint2/inst/htmljs folder. During testing, when I run the tests_run() command the animint library is installed from the main repository. Since my code is not in the main repository, I cannot test this feature. |
I understand you are having a problem testing your changes to the js code, is that right? > system.file("htmljs/animint.js", package="animint2", mustWork=TRUE)
[1] "C:/Users/hoct2726/AppData/Local/R/win-library/4.5/animint2/htmljs/animint.js" does that help? |
yes now its working that is basic testing https://www.youtube.com/watch?v=TDXU5QgksOg library(testthat)
library(XML)
data <- data.frame(
year = rep(2000:2005, each = 3),
country = rep(c("USA", "Canada", "Mexico"), times = 6),
life_expectancy = c(78, 80, 76, 79, 81, 77, 80, 82, 78, 81, 83, 79, 82, 84, 80, 83, 85, 81),
fertility_rate = c(1.8, 1.7, 2.1, 1.9, 1.8, 2.2, 1.9, 1.8, 2.3, 2.0, 1.9, 2.4, 2.1, 2.0, 2.5, 2.2, 2.1, 2.6),
population = c(300, 100, 150, 310, 110, 160, 320, 120, 170, 330, 130, 180, 340, 140, 190, 350, 150, 200)
)
my_plot <- list(
pointPlot = ggplot(data, aes(x = life_expectancy, y = fertility_rate)) +
animint2::geom_point(
aes(size = population, color = country),
help = "Each point represents life expectancy and fertility rate for a given country.",
showSelected = "year",
clickSelects = "country"
) +
labs(title = "Life Expectancy vs. Fertility Rate", x = "Life Expectancy", y = "Fertility Rate"),
vlinePlot = ggplot(data, aes(x = life_expectancy, y = fertility_rate)) +
animint2::geom_vline(
xintercept = 80,
linetype = "dashed",
color = "red",
help = "Vertical line represents a life expectancy threshold of 80."
)
)
map <- animint2HTML(my_plot)
test_that("Check tour navigation and content", {
clickID("start_tour")
html_content <- getHTML()
html_text <- if(inherits(html_content, "XMLInternalDocument")) {
saveXML(html_content)
} else {
as.character(html_content)
}
first_element_exists <- length(
getNodeSet(
htmlParse(html_text, asText = TRUE),
"//div[contains(@class, 'driver-popover-title')][starts-with(text(), 'Geom1')]"
)
) > 0
expect_true(first_element_exists, "Expected 'Geom1_point_pointPlot' element not found in the tour popup")
runtime_evaluate_helper(
class_name = "driver-popover-next-btn",
list_num = 0,
dispatch_event = TRUE
)
html_content <- getHTML()
html_text <- if(inherits(html_content, "XMLInternalDocument")) {
saveXML(html_content)
} else {
as.character(html_content)
}
second_element_exists <- length(
getNodeSet(
htmlParse(html_text, asText = TRUE),
"//div[contains(@class, 'driver-popover-title') and contains(text(), 'Geom2_vline_vlinePlot')]"
)
) > 0
expect_true(second_element_exists, "Expected 'Geom2_vline_vlinePlot' title not found after clicking Next")
}) |
good start but
|
https://youtu.be/Xb9DWp2zbvk here is the video with explanation library(animint2)
library(testthat)
library(XML)
data <- data.frame(
year = rep(2000:2005, each = 3),
country = rep(c("USA", "Canada", "Mexico"), times = 6),
life_expectancy = c(78, 80, 76, 79, 81, 77, 80, 82, 78, 81, 83, 79, 82, 84, 80, 83, 85, 81),
fertility_rate = c(1.8, 1.7, 2.1, 1.9, 1.8, 2.2, 1.9, 1.8, 2.3, 2.0, 1.9, 2.4, 2.1, 2.0, 2.5, 2.2, 2.1, 2.6),
population = c(300, 100, 150, 310, 110, 160, 320, 120, 170, 330, 130, 180, 340, 140, 190, 350, 150, 200)
)
my_plot <- list(
pointPlot = ggplot(data, aes(x = life_expectancy, y = fertility_rate)) +
animint2::geom_point(
aes(size = population, color = country),
help = "Each point represents life expectancy and fertility rate for a given country.",
showSelected = "year",
clickSelects = "country"
) +
labs(title = "Life Expectancy vs. Fertility Rate", x = "Life Expectancy", y = "Fertility Rate"),
vlinePlot = ggplot(data, aes(x = life_expectancy, y = fertility_rate)) +
animint2::geom_vline(
xintercept = 80,
linetype = "dashed",
color = "red",
help = "Vertical line represents a life expectancy threshold of 80."
)
)
map <- animint2HTML(my_plot)
count_elements <- function(html_content, xpath) {
html_text <- if (inherits(html_content, "XMLInternalDocument")) {
saveXML(html_content)
} else {
as.character(html_content)
}
length(getNodeSet(htmlParse(html_text, asText = TRUE), xpath))
}
test_that("Check tour navigation and content", {
info <- list(html_updated1 = getHTML())
no_updates_ranges1 <- get_pixel_ranges(info$html_updated1, "geom1_point_pointPlot")
print("Pixel ranges for geom1_point_pointPlot:")
print(no_updates_ranges1)
expect_gt(
length(no_updates_ranges1$x),
0,
"Expected at least one x value in pixel ranges for geom1_point_pointPlot"
)
expect_gt(
length(no_updates_ranges1$y),
0,
"Expected at least one y value in pixel ranges for geom1_point_pointPlot"
)
title_count <- count_elements(
getHTML(),
"//*[contains(text(), 'Life Expectancy vs. Fertility Rate')]"
)
expect_gt(
title_count,
0,
"Expected the text 'Life Expectancy vs. Fertility Rate' to be present in the plot title."
)
clickID("start_tour")
first_element_count <- count_elements(
getHTML(),
"//div[contains(@class, 'driver-popover-title')][contains(text(), 'Geom1_point_pointPlot')]"
)
expect_gt(
first_element_count,
0,
"Expected at least one 'Geom1_point_pointPlot' element in the tour popup"
)
runtime_evaluate_helper(
class_name = "driver-popover-next-btn",
list_num = 0,
dispatch_event = TRUE
)
second_element_count <- count_elements(
getHTML(),
"//div[contains(@class, 'driver-popover-title') and contains(text(), 'Geom2_vline_vlinePlot')]"
)
expect_gt(
second_element_count,
0,
"Expected 'Geom2_vline_vlinePlot' element after clicking Next"
)
}) |
this is better
However your video does not show you running the test in the chromote, so it is not clear that you understand how to use chromote. Please demonstrate that you know how to use chromote. Also please remove empty lines inside of test_that blocks of code. |
https://youtu.be/1UqUFtgI6O8 here I used multiple test_that function https://github.com/animint/animint2/wiki/Chromote-testing-documentation I used this to know about testing and few repo codes |
I see in the video that you ran Also I asked you to "run your test code line by line, one at a time, explaining what happens after each line of code" but you did not do that. You did |
Please revise your code to avoid the issues mentioned here: https://docs.google.com/document/d/1W6-HdQLgHayOFXaQtscO5J5yf05G7E6KeXyiBJFcT7A/edit?tab=t.0 Please avoid using print() in tests. Previously I asked you to "Please remove empty lines inside of test_that blocks of code." but I still see some empty lines. (also please remove empty lines inside functions like count_elements) Also, did you push your most recent code to this branch? |
after running each part I added new test that I did not show in video
I am not understanding what it means do I need to use debug pointers or run a block of code using ctl + enter. If I select this block in RStudio and use ctl + enter then 5 prints > value <- 5
> cat(value)
5
Okay I will fix it
I pushed guided tour code, but test part did not push |
please push test code so it can be reviewed |
for the videos yes you should use control-enter or similar to execute one line at a time, and explain each line, as in this video. https://www.youtube.com/watch?v=SRdzg-gzKXs&list=PLwc48KSH3D1M78ilQi35KPe2GHa7B_Rme&index=1&t=900s |
https://www.youtube.com/watch?v=nFIQJ36O86M here is the test |
this is much better, thanks! and that definitely demonstrates you know how to use the chromote testing, so that is enough for your gsoc application at least. a couple of suggestions if you have to do other videos like this
also for the test code:
|
okay I will try
should I make another video for this
Geom1_etc is text here steps.push({
element: '.' + geom,
popover: {
title: geom.charAt(0).toUpperCase() + geom.slice(1),
description: `${helpText}${showSelected ? ` Data are shown for the current selection of: ${showSelected}.` : ''}${clickSelects ? ` Click to change selection of: ${clickSelects}.` : ''}`,
}, |
no need to do another video, unless you want to. |
It would be better, should I implement it |
yes please |
I am not understanding how I would extract title, description from geom_text(title="some text instead of geom1_etc", description="longer text describing what is displayed") and geom_text is a function also but user can give title this way animint2::geom_point(
aes(size = population, color = country),
title = " Random Title",
help = "Random description",
showSelected = "year",
clickSelects = "country"
) and I changed animint.js code popover: {
title: `${title}`,
description: `${helpText}<br>${showSelected ? ` Data are shown for the current selection of: ${showSelected}.` : ''}<br>${clickSelects ? ` Click to change selection of: ${clickSelects}.` : ''}`,
}, and should I keep newlines in description |
looks good thanks for all of your hard work on this. |
.vscode/settings.json
Outdated
@@ -0,0 +1,3 @@ | |||
{ | |||
"liveServer.settings.port": 5501 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please undo this addition, and instead put settings.json in .gitignore
I see there are lots of formatting/style changes in animint.js which is not desirable for a new feature PR like this. please move the formatting/style changes to a separate PR. and in this PR please keep only the changes that are related to adding the new guided tour feature. That makes the new feature PR much easier to review. click on "Files Changed" tab to double check what changes are in each PR. |
those changes happen automatically by the vscode extension. |
.vscode/settings.json
Outdated
@@ -1,3 +1,3 @@ | |||
{ | |||
"liveServer.settings.port": 5501 | |||
"liveServer.settings.port":5501 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please remove from git
size colour x y showSelectedlegendcolour clickSelects showSelected1 fill | ||
5.47213595499958 #619CFF 78 1.8 USA USA 2000 #619CFF | ||
1 #F8766D 80 1.7 Canada Canada 2000 #F8766D | ||
3.23606797749979 #00BA38 76 2.1 Mexico Mexico 2000 #00BA38 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please remove this and all generated files from git
tests/testthat/FluView/rrt.R
Outdated
test_that("Driver.js guided tour displays correct help text", { | ||
|
||
# Start RSelenium with Microsoft Edge (or any other browser) | ||
rD <- rsDriver(browser = "edge", port = 4444) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use new chromote testing, not edge
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use new chromote testing, not edge
that was generated later hence I deleted it totally
@tdhock I am not understanding the error. Can I re-run these jobs with debug logging? |
if you add print statements in your test, they should show up in the log on github |
360 minute means timeout, so maybe an infinite loop? or maybe a heisenbug, could work if we just restart? |
Thanks very much for this contribution!
seems like there is some issue with show.val etc in the plot.json, I will look into fixing that. also I think we should add a test case that involves named clickSelects/showSelected, https://rcdata.nau.edu/genomic-ml/animint2-manual/Ch14-PeakSegJoint.html |
djs.list <- driverjs_get(info$html) | ||
test_that("no title nor description initially", { | ||
expect_identical(djs.list$title, list()) | ||
expect_identical(djs.list$description, list()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hi @biplab-sutradhar this is what I meant, when I asked you to test the same properties before and after interaction.
here we test title and description before clicking Start tour, then below we check that they change after clicking Start tour and Next.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay now I understand it
ok great, thanks for the contribution. I will merge now and we can follow up with more test cases later if needed. |
added guided tour feature
Closes #150