Skip to content

Commit

Permalink
test: add new suite for inlineStylesheets configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
lilnasy committed Apr 18, 2023
1 parent 33b72c2 commit 869a369
Show file tree
Hide file tree
Showing 8 changed files with 467 additions and 0 deletions.
285 changes: 285 additions & 0 deletions packages/astro/test/css-inline-stylesheets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
import { expect } from 'chai';
import * as cheerio from 'cheerio';
import { loadFixture } from './test-utils.js';
import testAdapter from './test-adapter.js';

describe('Setting inlineStylesheets to never in static output', () => {
let fixture;

before(async () => {
fixture = await loadFixture({
root: './fixtures/css-inline-stylesheets/',
output: 'static',
experimental: {
inlineStylesheets: 'never',
},
});
await fixture.build();
});

it('Does not render any <style> tags', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerio.load(html);

expect($('style').toArray()).to.be.empty;
});

describe('Inspect linked stylesheets', () => {
// object, so it can be passed by reference
const allStyles = {};

before(async () => {
allStyles.value = await stylesFromStaticOutput(fixture);
});

commonExpectations(allStyles);
});
});

describe('Setting inlineStylesheets to never in server output', () => {
let app;

before(async () => {
const fixture = await loadFixture({
root: './fixtures/css-inline-stylesheets/',
output: 'server',
adapter: testAdapter(),
experimental: {
inlineStylesheets: 'never',
},
});
await fixture.build();
app = await fixture.loadTestAdapterApp();
});

it('Does not render any <style> tags', async () => {
const request = new Request('http://example.com/');
const response = await app.render(request);
const html = await response.text();
const $ = cheerio.load(html);

expect($('style').toArray()).to.be.empty;
});

describe('Inspect linked stylesheets', () => {
const allStyles = {};

before(async () => {
allStyles.value = await stylesFromServer(app);
});

commonExpectations(allStyles);
});
});

describe('Setting inlineStylesheets to auto in static output', () => {
let fixture;

before(async () => {
fixture = await loadFixture({
root: './fixtures/css-inline-stylesheets/',
output: 'static',
experimental: {
inlineStylesheets: 'auto',
},
vite: {
build: {
assetsInlineLimit: 512,
},
},
});
await fixture.build();
});

it('Renders some <style> and some <link> tags', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerio.load(html);

// the count of style/link tags depends on our css chunking logic
// this test should be updated if it changes
expect($('style')).to.have.lengthOf(3);
expect($('link[rel=stylesheet]')).to.have.lengthOf(1);
});

describe('Inspect linked and inlined stylesheets', () => {
const allStyles = {};

before(async () => {
allStyles.value = await stylesFromStaticOutput(fixture);
});

commonExpectations(allStyles);
});
});

describe('Setting inlineStylesheets to auto in server output', () => {
let app;

before(async () => {
const fixture = await loadFixture({
root: './fixtures/css-inline-stylesheets/',
output: 'server',
adapter: testAdapter(),
experimental: {
inlineStylesheets: 'auto',
},
vite: {
build: {
assetsInlineLimit: 512,
},
},
});
await fixture.build();
app = await fixture.loadTestAdapterApp();
});

it('Renders some <style> and some <link> tags', async () => {
const request = new Request('http://example.com/');
const response = await app.render(request);
const html = await response.text();
const $ = cheerio.load(html);

// the count of style/link tags depends on our css chunking logic
// this test should be updated if it changes
expect($('style')).to.have.lengthOf(3);
expect($('link[rel=stylesheet]')).to.have.lengthOf(1);
});

describe('Inspect linked and inlined stylesheets', () => {
const allStyles = {};

before(async () => {
allStyles.value = await stylesFromServer(app);
});

commonExpectations(allStyles);
});
});

describe('Setting inlineStylesheets to always in static output', () => {
let fixture;

before(async () => {
fixture = await loadFixture({
root: './fixtures/css-inline-stylesheets/',
output: 'static',
experimental: {
inlineStylesheets: 'always',
},
});
await fixture.build();
});

it('Does not render any <link> tags', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerio.load(html);

expect($('link[rel=stylesheet]').toArray()).to.be.empty;
});

describe('Inspect inlined stylesheets', () => {
const allStyles = {};

before(async () => {
allStyles.value = await stylesFromStaticOutput(fixture);
});

commonExpectations(allStyles);
});
});

describe('Setting inlineStylesheets to always in server output', () => {
let app;

before(async () => {
const fixture = await loadFixture({
root: './fixtures/css-inline-stylesheets/',
output: 'server',
adapter: testAdapter(),
experimental: {
inlineStylesheets: 'always',
},
});
await fixture.build();
app = await fixture.loadTestAdapterApp();
});

it('Does not render any <link> tags', async () => {
const request = new Request('http://example.com/');
const response = await app.render(request);
const html = await response.text();
const $ = cheerio.load(html);

expect($('link[rel=stylesheet]').toArray()).to.be.empty;
});

describe('Inspect inlined stylesheets', () => {
const allStyles = {};

before(async () => {
allStyles.value = await stylesFromServer(app);
});

commonExpectations(allStyles);
});
});

async function stylesFromStaticOutput(fixture) {
const html = await fixture.readFile('/index.html');
const $ = cheerio.load(html);

const links = $('link[rel=stylesheet]');
const hrefs = links.map((_, linkEl) => linkEl.attribs.href).toArray();
const allLinkedStylesheets = await Promise.all(hrefs.map((href) => fixture.readFile(href)));
const allLinkedStyles = allLinkedStylesheets.join('');

const styles = $('style');
const allInlinedStylesheets = styles.map((_, styleEl) => styleEl.children[0].data).toArray();
const allInlinedStyles = allInlinedStylesheets.join('');

return allLinkedStyles + allInlinedStyles;
}

async function stylesFromServer(app) {
const request = new Request('http://example.com/');
const response = await app.render(request);
const html = await response.text();
const $ = cheerio.load(html);

const links = $('link[rel=stylesheet]');
const hrefs = links.map((_, linkEl) => linkEl.attribs.href).toArray();
const allLinkedStylesheets = await Promise.all(
hrefs.map(async (href) => {
const cssRequest = new Request(`http://example.com${href}`);
const cssResponse = await app.render(cssRequest);
return await cssResponse.text();
})
);
const allLinkedStyles = allLinkedStylesheets.join('');

const styles = $('style');
const allInlinedStylesheets = styles.map((_, styleEl) => styleEl.children[0].data).toArray();
const allInlinedStyles = allInlinedStylesheets.join('');
return allLinkedStyles + allInlinedStyles;
}

function commonExpectations(allStyles) {
it('Includes all authored css', () => {
// authored in imported.css
expect(allStyles.value).to.include('.bg-lightcoral');

// authored in index.astro
expect(allStyles.value).to.include('#welcome');

// authored in components/Button.astro
expect(allStyles.value).to.include('.variant-outline');

// authored in layouts/Layout.astro
expect(allStyles.value).to.include('Menlo');
});

it('Styles used both in content layout and directly in page are included only once', () => {
// authored in components/Button.astro
expect(allStyles.value.match(/cubic-bezier/g)).to.have.lengthOf(1);
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@test/css-inline-stylesheets",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
const { class: className = '', style, href } = Astro.props;
const { variant = 'primary' } = Astro.props;
---

<span class:list={[`link pixel variant-${variant}`, className]} >
<a {href}>
<span><slot /></span>
</a>
</span>

<style>
.link {
--border-radius: 8;
--duration: 200ms;
--delay: 30ms;
--background: linear-gradient(180deg, var(--link-color-stop-a), var(--link-color-stop-b));
display: flex;
color: white;
font-size: 1.25rem;
width: max-content;
}
a {
display: flex;
align-items: center;
justify-content: center;
padding: 0.67rem 1.25rem;
width: 100%;
height: 100%;
text-decoration: none;
color: inherit !important;
/* Indicates the button boundaries for forced colors users in older browsers */
outline: 1px solid transparent;
}

@media (forced-colors: active) {
a {
border: 1px solid LinkText;
}
}

a > :global(* + *) {
margin-inline-start: 0.25rem;
}

.variant-primary {
--variant: primary;
--background: linear-gradient(180deg, var(--link-color-stop-a), var(--link-color-stop-b));
}
.variant-primary:hover,
.variant-primary:focus-within {
--link-color-stop-a: #6d39ff;
--link-color-stop-b: #af43ff;
}
.variant-primary:active {
--link-color-stop-a: #5f31e1;
--link-color-stop-b: #a740f3;
}

.variant-outline {
--variant: outline;
--background: none;
color: var(--background);
}
.variant-outline > a::before {
position: absolute;
top: 0;
right: calc(var(--pixel-size) * 1px);
bottom: calc(var(--pixel-size) * 1px);
left: calc(var(--pixel-size) * 1px);
content: '';
display: block;
transform-origin: bottom center;
background: linear-gradient(to top, var(--background), rgba(255, 255, 255, 0));
opacity: 0.3;
transform: scaleY(0);
transition: transform 200ms cubic-bezier(0.22, 1, 0.36, 1);
}
.variant-outline:hover > a::before,
.variant-outline:focus-within > a::before {
transform: scaleY(1);
}
.variant-outline:active > a::before {
transform: scaleY(1);
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: Endeavour
description: 'Learn about the Endeavour NASA space shuttle.'
publishedDate: 'Sun Jul 11 2021 00:00:00 GMT-0400 (Eastern Daylight Time)'
layout: '../../layouts/Layout.astro'
tags: [space, 90s]
---

**Source:** [Wikipedia](https://en.wikipedia.org/wiki/Space_Shuttle_Endeavour)

Space Shuttle Endeavour (Orbiter Vehicle Designation: OV-105) is a retired orbiter from NASA's Space Shuttle program and the fifth and final operational Shuttle built. It embarked on its first mission, STS-49, in May 1992 and its 25th and final mission, STS-134, in May 2011. STS-134 was expected to be the final mission of the Space Shuttle program, but with the authorization of STS-135, Atlantis became the last shuttle to fly.

The United States Congress approved the construction of Endeavour in 1987 to replace the Space Shuttle Challenger, which was destroyed in 1986.

NASA chose, on cost grounds, to build much of Endeavour from spare parts rather than refitting the Space Shuttle Enterprise, and used structural spares built during the construction of Discovery and Atlantis in its assembly.
Loading

0 comments on commit 869a369

Please sign in to comment.