1
0

lib.rs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // This test is used by playwright configured in the root of the repo
  2. // Tests:
  3. // - SEO without JS
  4. // - Streaming hydration
  5. // - Suspense
  6. // - Server functions
  7. //
  8. // Without Javascript, content may not load into the right location, but it should still be somewhere in the html even if it is invisible
  9. use dioxus::prelude::*;
  10. use serde::{Deserialize, Serialize};
  11. pub fn app() -> Element {
  12. rsx! {
  13. SuspenseBoundary {
  14. fallback: move |_| rsx! {},
  15. document::Style {
  16. href: asset!("/assets/style.css")
  17. }
  18. LoadTitle {}
  19. }
  20. MessageWithLoader { id: 0 }
  21. }
  22. }
  23. #[component]
  24. fn MessageWithLoader(id: usize) -> Element {
  25. rsx! {
  26. SuspenseBoundary {
  27. fallback: move |_| rsx! {
  28. "Loading {id}..."
  29. },
  30. Message { id }
  31. }
  32. }
  33. }
  34. #[component]
  35. fn LoadTitle() -> Element {
  36. let title = use_server_future(move || server_content(0))?()
  37. .unwrap()
  38. .unwrap();
  39. rsx! {
  40. "title loaded"
  41. document::Title { "{title.title}" }
  42. }
  43. }
  44. #[component]
  45. fn Message(id: usize) -> Element {
  46. let message = use_server_future(move || server_content(id))?()
  47. .unwrap()
  48. .unwrap();
  49. rsx! {
  50. h2 {
  51. id: "title-{id}",
  52. "{message.title}"
  53. }
  54. p {
  55. id: "body-{id}",
  56. "{message.body}"
  57. }
  58. div {
  59. id: "children-{id}",
  60. padding: "10px",
  61. for child in message.children {
  62. MessageWithLoader { id: child }
  63. }
  64. }
  65. }
  66. }
  67. #[derive(Clone, Serialize, Deserialize)]
  68. pub struct Content {
  69. title: String,
  70. body: String,
  71. children: Vec<usize>,
  72. }
  73. #[server]
  74. async fn server_content(id: usize) -> Result<Content, ServerFnError> {
  75. let content_tree = [
  76. Content {
  77. title: "The robot says hello world".to_string(),
  78. body: "The robot becomes sentient and says hello world".to_string(),
  79. children: vec![1, 2, 3],
  80. },
  81. Content {
  82. title: "The world says hello back".to_string(),
  83. body: "In a stunning turn of events, the world collectively unites and says hello back"
  84. .to_string(),
  85. children: vec![4],
  86. },
  87. Content {
  88. title: "Goodbye Robot".to_string(),
  89. body: "The robot says goodbye".to_string(),
  90. children: vec![],
  91. },
  92. Content {
  93. title: "Goodbye World".to_string(),
  94. body: "The world says goodbye".to_string(),
  95. children: vec![],
  96. },
  97. Content {
  98. title: "Hello World".to_string(),
  99. body: "The world says hello again".to_string(),
  100. children: vec![],
  101. },
  102. ];
  103. tokio::time::sleep(std::time::Duration::from_millis(1000)).await;
  104. Ok(content_tree[id].clone())
  105. }