Skip to content

Commit d377b92

Browse files
committed
feat: version and locale aware home, default stable, version alerts
1 parent ba911ce commit d377b92

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1294
-633
lines changed

tools/website-e2e/tests/navigation.rs

Lines changed: 186 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,32 @@ async fn assert_no_element(client: &fantoccini::Client, css: &str) {
146146
assert!(els.is_empty(), "expected no elements for: {css}");
147147
}
148148

149+
async fn click_version_option(client: &fantoccini::Client, label: &str) {
150+
let btn = client
151+
.find(Locator::Css(
152+
".items > .dropdown:nth-of-type(1) .dropdown-btn",
153+
))
154+
.await
155+
.unwrap();
156+
btn.click().await.unwrap();
157+
tokio::time::sleep(Duration::from_millis(200)).await;
158+
159+
let items = client
160+
.find_all(Locator::Css(
161+
".items > .dropdown:nth-of-type(1) .dropdown-item",
162+
))
163+
.await
164+
.unwrap();
165+
for item in items {
166+
if item.text().await.unwrap().trim() == label {
167+
item.click().await.unwrap();
168+
tokio::time::sleep(Duration::from_millis(500)).await;
169+
return;
170+
}
171+
}
172+
panic!("version option '{}' not found", label);
173+
}
174+
149175
async fn assert_hreflang_set(client: &fantoccini::Client, expected: &[&str]) {
150176
let els = client
151177
.find_all(Locator::Css("link[hreflang]"))
@@ -169,17 +195,17 @@ async fn version_and_language_navigation() {
169195
let base = format!("http://{addr}");
170196
let client = make_client().await;
171197

172-
// Step 1: visit /docs/concepts/router
198+
// Step 1: visit /docs/concepts/router (now 0.23, latest stable)
173199
client
174200
.goto(&format!("{base}/docs/concepts/router"))
175201
.await
176202
.unwrap();
177203
tokio::time::sleep(Duration::from_millis(500)).await;
178204

179-
assert_version_selector(&client, "Next").await;
205+
assert_version_selector(&client, "0.23").await;
180206
assert_lang_selector(&client, "English").await;
181207

182-
// Step 2: expand version selector, verify options, click 0.23
208+
// Step 2: expand version selector, verify options, click Next
183209
{
184210
let btn = client
185211
.find(Locator::Css(
@@ -204,8 +230,8 @@ async fn version_and_language_navigation() {
204230
v
205231
};
206232
assert!(
207-
labels.contains(&"0.23".to_string()),
208-
"0.23 not in version options: {:?}",
233+
labels.contains(&"Next".to_string()),
234+
"Next not in version options: {:?}",
209235
labels
210236
);
211237
assert!(
@@ -225,27 +251,27 @@ async fn version_and_language_navigation() {
225251
);
226252

227253
for item in items {
228-
if item.text().await.unwrap().trim() == "0.23" {
254+
if item.text().await.unwrap().trim() == "Next" {
229255
item.click().await.unwrap();
230256
break;
231257
}
232258
}
233259
tokio::time::sleep(Duration::from_millis(500)).await;
234260
}
235261

236-
// Step 3: should be at /docs/0.23/concepts/router
262+
// Step 3: should be at /docs/next/concepts/router
237263
let url = client.current_url().await.unwrap();
238-
assert_path(&url, "/docs/0.23/concepts/router");
239-
assert_version_selector(&client, "0.23").await;
264+
assert_path(&url, "/docs/next/concepts/router");
265+
assert_version_selector(&client, "Next").await;
240266
assert_lang_selector(&client, "English").await;
241267

242268
// Step 4: switch language to Japanese
243269
click_lang_option(&client, "\u{65e5}\u{672c}\u{8a9e}").await;
244270

245271
let url = client.current_url().await.unwrap();
246-
assert_path(&url, "/ja/docs/0.23/concepts/router");
272+
assert_path(&url, "/ja/docs/next/concepts/router");
247273
assert_lang_selector(&client, "\u{65e5}\u{672c}\u{8a9e}").await;
248-
assert_version_selector(&client, "0.23").await;
274+
assert_version_selector(&client, "Next").await;
249275

250276
let body_text = client
251277
.find(Locator::Css("main"))
@@ -256,15 +282,15 @@ async fn version_and_language_navigation() {
256282
.unwrap();
257283
assert!(
258284
page_looks_japanese(&body_text),
259-
"page at /ja/docs/0.23/concepts/router does not look Japanese"
285+
"page at /ja/docs/next/concepts/router does not look Japanese"
260286
);
261287

262288
// Step 5: click "Getting Started" sidebar category
263289
click_sidebar_category(&client, "Getting Started").await;
264290

265291
let url = client.current_url().await.unwrap();
266-
assert_path(&url, "/ja/docs/0.23/getting-started");
267-
assert_version_selector(&client, "0.23").await;
292+
assert_path(&url, "/ja/docs/next/getting-started");
293+
assert_version_selector(&client, "Next").await;
268294
assert_lang_selector(&client, "\u{65e5}\u{672c}\u{8a9e}").await;
269295

270296
client.close().await.unwrap();
@@ -491,7 +517,7 @@ async fn head_meta_tags() {
491517
assert_no_element(&client, r#"meta[name="docsearch:version"]"#).await;
492518
assert_no_element(&client, r#"script[type="application/ld+json"]"#).await;
493519

494-
// --- English docs page ---
520+
// --- English docs page (0.23, latest stable) ---
495521
client
496522
.goto(&format!("{base}/docs/concepts/router"))
497523
.await
@@ -539,17 +565,33 @@ async fn head_meta_tags() {
539565
&client,
540566
r#"meta[name="docsearch:version"]"#,
541567
"content",
542-
"next",
568+
"0.23",
543569
)
544570
.await;
545571

546572
assert_meta_exists(&client, r#"meta[name="description"]"#).await;
547573
assert_meta_exists(&client, r#"meta[property="og:description"]"#).await;
548574
assert_meta_exists(&client, r#"script[type="application/ld+json"]"#).await;
549575

550-
// --- Japanese versioned docs page ---
576+
// --- English Next docs page ---
551577
client
552-
.goto(&format!("{base}/ja/docs/0.23/concepts/router"))
578+
.goto(&format!("{base}/docs/next/concepts/router"))
579+
.await
580+
.unwrap();
581+
tokio::time::sleep(Duration::from_millis(500)).await;
582+
583+
assert_meta_attr(&client, "html", "lang", "en").await;
584+
assert_meta_attr(
585+
&client,
586+
r#"meta[name="docsearch:version"]"#,
587+
"content",
588+
"next",
589+
)
590+
.await;
591+
592+
// --- Japanese docs page (0.23, latest stable) ---
593+
client
594+
.goto(&format!("{base}/ja/docs/concepts/router"))
553595
.await
554596
.unwrap();
555597
tokio::time::sleep(Duration::from_millis(500)).await;
@@ -573,14 +615,14 @@ async fn head_meta_tags() {
573615
&client,
574616
r#"meta[property="og:url"]"#,
575617
"content",
576-
"https://yew.rs/ja/docs/0.23/concepts/router",
618+
"https://yew.rs/ja/docs/concepts/router",
577619
)
578620
.await;
579621
assert_meta_attr(
580622
&client,
581623
r#"link[rel="canonical"]"#,
582624
"href",
583-
"https://yew.rs/ja/docs/0.23/concepts/router",
625+
"https://yew.rs/ja/docs/concepts/router",
584626
)
585627
.await;
586628
assert_meta_attr(&client, r#"meta[property="og:locale"]"#, "content", "ja").await;
@@ -645,3 +687,127 @@ async fn hreflang_tags() {
645687

646688
client.close().await.unwrap();
647689
}
690+
691+
#[tokio::test]
692+
async fn home_page_versioned_urls_exist() {
693+
let addr = start_file_server(&build_dir()).await;
694+
let base = format!("http://{addr}");
695+
696+
// Main home pages (latest stable)
697+
assert_status(&base, "/", 200).await;
698+
assert_status(&base, "/ja/", 200).await;
699+
assert_status(&base, "/zh-Hans/", 200).await;
700+
assert_status(&base, "/zh-Hant/", 200).await;
701+
702+
// Next versioned home pages
703+
assert_status(&base, "/next/", 200).await;
704+
assert_status(&base, "/ja/next/", 200).await;
705+
assert_status(&base, "/zh-Hans/next/", 200).await;
706+
assert_status(&base, "/zh-Hant/next/", 200).await;
707+
708+
// 0.22 versioned home pages
709+
assert_status(&base, "/0.22/", 200).await;
710+
assert_status(&base, "/ja/0.22/", 200).await;
711+
assert_status(&base, "/zh-Hans/0.22/", 200).await;
712+
assert_status(&base, "/zh-Hant/0.22/", 200).await;
713+
714+
// 0.21 versioned home pages
715+
assert_status(&base, "/0.21/", 200).await;
716+
assert_status(&base, "/ja/0.21/", 200).await;
717+
718+
// 0.20 versioned home pages
719+
assert_status(&base, "/0.20/", 200).await;
720+
assert_status(&base, "/ja/0.20/", 200).await;
721+
}
722+
723+
#[tokio::test]
724+
async fn home_page_version_selector() {
725+
let addr = start_file_server(&build_dir()).await;
726+
let base = format!("http://{addr}");
727+
let client = make_client().await;
728+
729+
// Main home shows latest stable (0.23)
730+
client.goto(&format!("{base}/")).await.unwrap();
731+
tokio::time::sleep(Duration::from_millis(500)).await;
732+
assert_version_selector(&client, "0.23").await;
733+
assert_lang_selector(&client, "English").await;
734+
735+
// No version badge or version banner on home page
736+
assert_no_element(&client, ".version-badge").await;
737+
assert_no_element(&client, ".version-banner").await;
738+
739+
// Click Next in version selector, navigate to /next/
740+
click_version_option(&client, "Next").await;
741+
let url = client.current_url().await.unwrap();
742+
assert_path(&url, "/next");
743+
assert_version_selector(&client, "Next").await;
744+
assert_no_element(&client, ".version-badge").await;
745+
assert_no_element(&client, ".version-banner").await;
746+
747+
// Switch language to Japanese on versioned home
748+
click_lang_option(&client, "\u{65e5}\u{672c}\u{8a9e}").await;
749+
let url = client.current_url().await.unwrap();
750+
assert_path(&url, "/ja/next");
751+
assert_version_selector(&client, "Next").await;
752+
assert_lang_selector(&client, "\u{65e5}\u{672c}\u{8a9e}").await;
753+
754+
// Switch version to 0.22
755+
click_version_option(&client, "0.22").await;
756+
let url = client.current_url().await.unwrap();
757+
assert_path(&url, "/ja/0.22");
758+
assert_version_selector(&client, "0.22").await;
759+
760+
// Switch back to latest (0.23), should go to /ja/
761+
click_version_option(&client, "0.23").await;
762+
let url = client.current_url().await.unwrap();
763+
assert_path(&url, "/ja");
764+
assert_version_selector(&client, "0.23").await;
765+
766+
client.close().await.unwrap();
767+
}
768+
769+
#[tokio::test]
770+
async fn home_page_learn_more_links() {
771+
let addr = start_file_server(&build_dir()).await;
772+
let base = format!("http://{addr}");
773+
let client = make_client().await;
774+
775+
// English home: "Learn more" links point to /docs/... (latest stable)
776+
client.goto(&format!("{base}/")).await.unwrap();
777+
tokio::time::sleep(Duration::from_millis(500)).await;
778+
779+
let links = client
780+
.find_all(Locator::Css(".card-footer a"))
781+
.await
782+
.unwrap();
783+
assert!(!links.is_empty(), "no Learn more links found");
784+
for link in &links {
785+
let href = link.attr("href").await.unwrap().unwrap();
786+
assert!(
787+
href.starts_with("/docs/"),
788+
"Learn more link should start with /docs/, got: {href}"
789+
);
790+
assert!(
791+
!href.contains("/docs/docs/"),
792+
"Learn more link has double /docs/: {href}"
793+
);
794+
}
795+
796+
// Japanese versioned home: links point to /ja/docs/0.22/...
797+
client.goto(&format!("{base}/ja/0.22/")).await.unwrap();
798+
tokio::time::sleep(Duration::from_millis(500)).await;
799+
800+
let links = client
801+
.find_all(Locator::Css(".card-footer a"))
802+
.await
803+
.unwrap();
804+
for link in &links {
805+
let href = link.attr("href").await.unwrap().unwrap();
806+
assert!(
807+
href.starts_with("/ja/docs/0.22/"),
808+
"ja/0.22 Learn more link should start with /ja/docs/0.22/, got: {href}"
809+
);
810+
}
811+
812+
client.close().await.unwrap();
813+
}

yew-rs/README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@ This builds only pages matching `/docs/getting-started`, skips wasm-opt (faster)
1616
## Interactive page picker
1717

1818
```sh
19-
cargo r -p yew-site-ssg -- --skip-wasm-opt --skip-capture --serve 8080
19+
cargo r -p yew-site-ssg -- --skip-wasm-opt --skip-capture --jobs 16 --serve 8080
2020
```
2121

2222
Without `--page`, the SSG shows an interactive fuzzy-searchable picker. Type to filter, space to toggle pages, enter to confirm. Press esc to build all pages.
2323

2424
In non-interactive environments (CI, piped stdin), it builds all pages automatically.
25+
26+
## Tests
27+
28+
`--skip-capture` saves time but the SSR tests will fail.

0 commit comments

Comments
 (0)