diff --git a/src/web/error.rs b/src/web/error.rs index 1463a69ff..b039d683a 100644 --- a/src/web/error.rs +++ b/src/web/error.rs @@ -93,3 +93,32 @@ impl From for IronError { IronError::new(err.compat(), Status::InternalServerError) } } + +#[cfg(test)] +mod tests { + use crate::test::wrapper; + use kuchiki::traits::TendrilSink; + + #[test] + fn check_404_page_content() { + wrapper(|env| { + let page = kuchiki::parse_html().one( + env.frontend() + .get("/page-which-doesnt-exist") + .send()? + .text()?, + ); + assert_eq!(page.select("#crate-title").unwrap().count(), 1); + assert_eq!( + page.select("#crate-title") + .unwrap() + .next() + .unwrap() + .text_contents(), + "The requested resource does not exist", + ); + + Ok(()) + }); + } +} diff --git a/src/web/releases.rs b/src/web/releases.rs index 5c957eef6..22498a8d7 100644 --- a/src/web/releases.rs +++ b/src/web/releases.rs @@ -1213,4 +1213,58 @@ mod tests { Ok(()) }); } + + #[test] + fn check_releases_page_content() { + // NOTE: this is a little fragile and may have to be updated if the HTML layout changes + let sel = ".pure-menu-horizontal>.pure-menu-list>.pure-menu-item>.pure-menu-link>.title"; + wrapper(|env| { + let tester = |url| { + let page = kuchiki::parse_html() + .one(env.frontend().get(url).send().unwrap().text().unwrap()); + assert_eq!(page.select("#crate-title").unwrap().count(), 1); + let not_matching = page + .select(sel) + .unwrap() + .map(|node| node.text_contents()) + .zip( + [ + "Recent", + "Stars", + "Recent Failures", + "Failures By Stars", + "Activity", + "Queue", + ] + .iter(), + ) + .filter(|(a, b)| a.as_str() != **b) + .collect::>(); + if not_matching.len() > 0 { + let not_found = not_matching.iter().map(|(_, b)| b).collect::>(); + let found = not_matching.iter().map(|(a, _)| a).collect::>(); + assert!( + not_matching.is_empty(), + "Titles did not match for URL `{}`: not found: {:?}, found: {:?}", + url, + not_found, + found, + ); + } + }; + + for url in &[ + "/releases", + "/releases/stars", + "/releases/recent-failures", + "/releases/failures", + "/releases/activity", + "/releases/queue", + ] { + tester(url); + } + + Ok(()) + }); + } } diff --git a/templates/about-base.html b/templates/about-base.html index fb35004f1..b61db89d9 100644 --- a/templates/about-base.html +++ b/templates/about-base.html @@ -1,32 +1,34 @@ {% extends "base.html" %} {% block header %} -
+
-

Docs.rs documentation

-
-
    - {% set text = "info-circle" | fas(fw=true) %} - {% set text = text ~ ' About' %} - {{ macros::active_link(expected="index", href="/about", text=text) }} +
    +

    Docs.rs documentation

    +
    +
      + {% set text = "info-circle" | fas(fw=true) %} + {% set text = text ~ ' About' %} + {{ macros::active_link(expected="index", href="/about", text=text) }} - {% set text = "fonticons" | fab(fw=true) %} - {% set text = text ~ ' Badges' %} - {{ macros::active_link(expected="badges", href="/about/badges", text=text) }} + {% set text = "fonticons" | fab(fw=true) %} + {% set text = text ~ ' Badges' %} + {{ macros::active_link(expected="badges", href="/about/badges", text=text) }} - {% set text = "cogs" | fas(fw=true) %} - {% set text = text ~ ' Builds' %} - {{ macros::active_link(expected="builds", href="/about/builds", text=text) }} + {% set text = "cogs" | fas(fw=true) %} + {% set text = text ~ ' Builds' %} + {{ macros::active_link(expected="builds", href="/about/builds", text=text) }} - {% set text = "table" | fas(fw=true) %} - {% set text = text ~ ' Metadata' %} - {{ macros::active_link(expected="metadata", href="/about/metadata", text=text) }} + {% set text = "table" | fas(fw=true) %} + {% set text = text ~ ' Metadata' %} + {{ macros::active_link(expected="metadata", href="/about/metadata", text=text) }} - {% set text = "road" | fas(fw=true) %} - {% set text = text ~ ' Shorthand URLs' %} - {{ macros::active_link(expected="redirections", href="/about/redirections", text=text) }} -
    + {% set text = "road" | fas(fw=true) %} + {% set text = text ~ ' Shorthand URLs' %} + {{ macros::active_link(expected="redirections", href="/about/redirections", text=text) }} +
+
-
+ {% endblock %} diff --git a/templates/header/package_navigation.html b/templates/header/package_navigation.html index f4d8cf44d..38cd6802d 100644 --- a/templates/header/package_navigation.html +++ b/templates/header/package_navigation.html @@ -15,85 +15,85 @@ {% macro package_navigation(title=false, metadata, platforms=false, active_tab) %}
- {# Page title #} -

- {%- if title -%} - {{ title }} - {%- else -%} - {{ metadata.name }} {{ metadata.version }} - {{ "copy" | far(id="clipboard", aria_label="Copy crate name and version information", fa=true) }} - {%- endif -%} -

+
+ {# The partial path of the crate, `:name/:release` #} + {%- set crate_path = metadata.name ~ "/" ~ metadata.version -%} - {# Page description #} -
- {%- if metadata.description -%} - {{ metadata.description }} - {%- endif -%} -
+ {# If docs are built, show a button for them #} -
- {# If there are platforms, show a dropdown with them #} - {%- if platforms -%} - - {%- endif -%} + {# Page title #} +

+ {%- if title -%} + {{ title }} + {%- else -%} + {{ metadata.name }} {{ metadata.version }} + {{ "copy" | far(id="clipboard", aria_label="Copy crate name and version information", fa=true) }} + {%- endif -%} +

+ + {# Page description #} +
+ {%- if metadata.description -%} + {{ metadata.description }} + {%- endif -%} +
- +
+ + {%- if metadata.rustdoc_status -%} + + {{ "book" | fas(fw=true) }} Documentation + + {%- endif -%}
{% endmacro package_navigation %} diff --git a/templates/releases/header.html b/templates/releases/header.html index d78806a89..2c1fe50ca 100644 --- a/templates/releases/header.html +++ b/templates/releases/header.html @@ -15,69 +15,71 @@ {% macro header(title, description, tab, author=false) %}
-

{{ title }}

-
{{ description | default(value="") }}
+
+

{{ title }}

+
{{ description | default(value="") }}
- {# This does double-duty as the search, so hide all tabs when we're searching something #} - {%- if tab != "search" -%} - + {%- endif -%} +
{% endmacro header %} diff --git a/templates/style/base.scss b/templates/style/base.scss index 40e119020..d5971ab5a 100644 --- a/templates/style/base.scss +++ b/templates/style/base.scss @@ -444,87 +444,119 @@ div.cratesfyi-package-container { border-bottom: 1px solid $color-border; margin-bottom: 20px; - h1 { - margin: 0; - padding: 15px 0 0 14px; + .container { + display: flex; + align-items: center; - &.no-description { - padding-bottom: 15px; - } - } + .description-container { + flex-grow: 3; - div.description { - font-family: $font-family-serif; - margin: 0; - padding: 0 0 15px 14px; - - @media #{$media-sm} { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - } - - div.description-in-rustdoc { - padding: 10px 0 10px 14px; - } + h1 { + margin: 0; + padding: 15px 14px; - .pure-menu { - margin-bottom: -1px; - padding-left: 14px; + @media #{$media-sm} { + padding: 15px 0 0 14px; + } - .pure-menu-link { - color: #666; - font-size: 14px; - padding: 0.4em 1em 0.3em 1em; + &.no-description { + padding-bottom: 15px; + } + } - .title { + div.description { display: none; @media #{$media-sm} { - display: inline; + font-family: $font-family-serif; + margin: 0; + padding: 2px 0 14px 15px; + display: block; } } - } - .pure-menu-active { - color: $color-standard; - background-color: #fff; - border-top: 1px solid $color-border; - border-left: 1px solid $color-border; - border-right: 1px solid $color-border; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom: 2px solid #fff; - } + div.description-in-rustdoc { + padding: 10px 0 10px 14px; + } - .pure-menu-active:hover { - background-color: #fff !important; - } + .pure-menu { + margin-bottom: -1px; + padding-left: 14px; - .pure-menu-link:hover { - color: #000; - background-color: inherit; - } - } + .pure-menu-link { + color: #666; + font-size: 14px; + padding: 0.4em 1em 0.3em 1em; - ul.platforms-menu { - float: right; - display: none; + .title { + display: none; - ul.pure-menu-children { - left: auto; - right: 0; - border: 1px solid $color-border; - border-radius: 2px; - } + @media #{$media-sm} { + display: inline; + } + } + } - .pure-menu-has-children > .pure-menu-link:after { - font-size: 14px; + .pure-menu-active { + color: $color-standard; + background-color: #fff; + border-top: 1px solid $color-border; + border-left: 1px solid $color-border; + border-right: 1px solid $color-border; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 2px solid #fff; + } + + .pure-menu-active:hover { + background-color: #fff !important; + } + + .pure-menu-link:hover { + color: #000; + background-color: inherit; + } + } + + ul.platforms-menu { + float: right; + display: none; + + ul.pure-menu-children { + left: auto; + right: 0; + border: 1px solid $color-border; + border-radius: 2px; + } + + .pure-menu-has-children > .pure-menu-link:after { + font-size: 14px; + } + + @media #{$media-sm} { + display: inline-block; + } + } } - @media #{$media-sm} { - display: inline-block; + .doc-link { + margin: 0 10px; + height: min-content; + background: #333; + color: #fff; + padding: 10px; + border: 1px solid #333; + border-radius: 5px; + display: flex; + + .fas { + margin-top: 2px; + margin-right: 6px; + } + + &:hover { + border-color: #3061f3; + } } } }