Skip to content

Commit

Permalink
feat: Enable importing CSS from node_modules (#9410)
Browse files Browse the repository at this point in the history
  • Loading branch information
tanbt committed Nov 30, 2020
1 parent 4c65750 commit 9b25ea8
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ function handleThemes(themeName, themesFolder, projectStaticAssetsOutputFolder)
copyThemeResources(themeFolder, projectStaticAssetsOutputFolder);
copyStaticAssets(themeProperties, projectStaticAssetsOutputFolder, logger);

const themeFile = generateThemeFile(themeFolder, themeName);
const themeFile = generateThemeFile(themeFolder, themeName, themeProperties);

fs.writeFileSync(path.resolve(themeFolder, themeName + '.js'), themeFile);
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const injectGlobalCss = (css, target) => {
* @param {string} themeName name of the handled theme
* @returns {string} theme file content
*/
function generateThemeFile(themeFolder, themeName) {
function generateThemeFile(themeFolder, themeName, themeProperties) {
const globalFiles = glob.sync('*.css', {
cwd: themeFolder,
nodir: true,
Expand Down Expand Up @@ -78,6 +78,15 @@ function generateThemeFile(themeFolder, themeName) {
globalCssCode.push(`injectGlobalCss(${variable}.toString(), target);\n`);
});

let i = 0;
if (themeProperties.importCss) {
themeProperties.importCss.forEach((cssPath) => {
const variable = 'module' + i++;
imports.push(`import ${variable} from '${cssPath}';\n`);
globalCssCode.push(`injectGlobalCss(${variable}.toString(), target);\n`);
});
}

componentsFiles.forEach((componentCss) => {
const filename = path.basename(componentCss);
const tag = filename.replace('.css', '');
Expand Down
1 change: 1 addition & 0 deletions flow-tests/test-themes/frontend/theme/app-theme/theme.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"importCss": ["@fortawesome/fontawesome-free/css/all.css"],
"assets": {
"@fortawesome/fontawesome-free": {
"svgs/regular/**": "fortawesome/icons"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class ThemeView extends Div {
public static final String SNOWFLAKE_ID = "fortawesome";
public static final String BUTTERFLY_ID = "butterfly";
public static final String OCTOPUSS_ID = "octopuss";
public static final String FONTAWESOME_ID = "font-awesome";
public static final String SUB_COMPONENT_ID = "sub-component";

public ThemeView() {
Expand All @@ -45,12 +46,16 @@ public ThemeView() {
Span octopuss = new Span();
octopuss.setId(OCTOPUSS_ID);

Span faText = new Span("This test is FontAwesome.");
faText.setClassName("fab");
faText.setId(FONTAWESOME_ID);

Image snowFlake = new Image(
"VAADIN/static/fortawesome/icons/snowflake.svg", "snowflake");
snowFlake.setHeight("1em");
snowFlake.setId(SNOWFLAKE_ID);

add(textSpan, snowFlake, subCss, butterfly, octopuss);
add(textSpan, snowFlake, subCss, butterfly, octopuss, faText);

add(new Div());
add(new MyPolymerField().withId(MY_POLYMER_ID));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.vaadin.testbench.TestBenchElement;

import static com.vaadin.flow.uitest.ui.theme.ThemeView.BUTTERFLY_ID;
import static com.vaadin.flow.uitest.ui.theme.ThemeView.FONTAWESOME_ID;
import static com.vaadin.flow.uitest.ui.theme.ThemeView.MY_LIT_ID;
import static com.vaadin.flow.uitest.ui.theme.ThemeView.MY_POLYMER_ID;
import static com.vaadin.flow.uitest.ui.theme.ThemeView.SNOWFLAKE_ID;
Expand All @@ -38,11 +39,11 @@ public class ThemeIT extends ChromeBrowserTest {
public void secondTheme_staticFilesNotCopied() {
getDriver().get(getRootURL() + "/path/VAADIN/static/img/bg.jpg");
Assert.assertFalse("app-theme static files should be copied",
driver.getPageSource().contains("HTTP ERROR 404 Not Found"));
driver.getPageSource().contains("HTTP ERROR 404 Not Found"));

getDriver().get(getRootURL() + "/path/VAADIN/static/no-copy.txt");
Assert.assertTrue("no-copy theme should not be handled",
driver.getPageSource().contains("HTTP ERROR 404 Not Found"));
driver.getPageSource().contains("HTTP ERROR 404 Not Found"));
}

@Test
Expand All @@ -53,34 +54,44 @@ public void applicationTheme_GlobalCss_isUsed() {

final WebElement body = findElement(By.tagName("body"));
Assert.assertEquals(
"url(\"" + getRootURL() + "/path/VAADIN/static/img/bg.jpg\")",
body.getCssValue("background-image"));
"url(\"" + getRootURL() + "/path/VAADIN/static/img/bg.jpg\")",
body.getCssValue("background-image"));

Assert.assertEquals("Ostrich", body.getCssValue("font-family"));

getDriver().get(getRootURL() + "/path/VAADIN/static/img/bg.jpg");
Assert.assertFalse("app-theme background file should be served",
driver.getPageSource().contains("Could not navigate"));
driver.getPageSource().contains("Could not navigate"));
}

@Test
public void applicationTheme_importCSS_isUsed() {
open();
checkLogsForErrors();

Assert.assertEquals("Imported FontAwesome css file should be applied.",
"Font Awesome 5 Brands", $(SpanElement.class).id(FONTAWESOME_ID)
.getCssValue("font-family"));
}

@Test
public void componentThemeIsApplied_forPolymerAndLit() {
open();
TestBenchElement myField = $(TestBenchElement.class).id(MY_POLYMER_ID);
TestBenchElement input = myField.$(TestBenchElement.class)
.id("vaadin-text-field-input-0");
.id("vaadin-text-field-input-0");
Assert.assertEquals("Polymer text field should have red background",
"rgba(255, 0, 0, 1)", input.getCssValue("background-color"));
"rgba(255, 0, 0, 1)", input.getCssValue("background-color"));

myField = $(TestBenchElement.class).id(MY_LIT_ID);
final SpanElement radio = myField.$(SpanElement.class).all().stream()
.filter(element -> "radio".equals(element.getAttribute("part")))
.findFirst().orElseGet(null);
.filter(element -> "radio".equals(element.getAttribute("part")))
.findFirst().orElseGet(null);

Assert.assertNotNull("Element with part='radio' was not found", radio);

Assert.assertEquals("Lit radiobutton should have red background",
"rgba(255, 0, 0, 1)", radio.getCssValue("background-color"));
"rgba(255, 0, 0, 1)", radio.getCssValue("background-color"));
}

@Test
Expand All @@ -89,10 +100,10 @@ public void subCssWithRelativePath_urlPathIsNotRelative() {
checkLogsForErrors();

Assert.assertEquals("Imported css file URLs should have been handled.",
"url(\"" + getRootURL()
+ "/path/VAADIN/static/icons/archive.png\")",
$(SpanElement.class).id(SUB_COMPONENT_ID)
.getCssValue("background-image"));
"url(\"" + getRootURL() +
"/path/VAADIN/static/icons/archive.png\")",
$(SpanElement.class).id(SUB_COMPONENT_ID)
.getCssValue("background-image"));
}

@Test
Expand All @@ -101,15 +112,15 @@ public void staticModuleAsset_servedFromStatic() {
checkLogsForErrors();

Assert.assertEquals(
"Node assets should have been copied to 'VAADIN/static'",
getRootURL()
+ "/path/VAADIN/static/fortawesome/icons/snowflake.svg",
$(ImageElement.class).id(SNOWFLAKE_ID).getAttribute("src"));
"Node assets should have been copied to 'VAADIN/static'",
getRootURL() +
"/path/VAADIN/static/fortawesome/icons/snowflake.svg",
$(ImageElement.class).id(SNOWFLAKE_ID).getAttribute("src"));

open(getRootURL() + "/path/" + $(ImageElement.class).id(SNOWFLAKE_ID)
.getAttribute("src"));
open(getRootURL() + "/path/" +
$(ImageElement.class).id(SNOWFLAKE_ID).getAttribute("src"));
Assert.assertFalse("Node static icon should be available",
driver.getPageSource().contains("HTTP ERROR 404 Not Found"));
driver.getPageSource().contains("HTTP ERROR 404 Not Found"));
}

@Test
Expand All @@ -118,23 +129,23 @@ public void nonThemeDependency_urlIsNotRewritten() {
checkLogsForErrors();

Assert.assertEquals("Relative non theme url should not be touched",
"url(\"" + getRootURL()
+ "/path/test/path/monarch-butterfly.jpg\")",
$(SpanElement.class).id(BUTTERFLY_ID)
.getCssValue("background-image"));
"url(\"" + getRootURL() +
"/path/test/path/monarch-butterfly.jpg\")",
$(SpanElement.class).id(BUTTERFLY_ID)
.getCssValue("background-image"));

Assert.assertEquals("Absolute non theme url should not be touched",
"url(\"" + getRootURL() + "/octopuss.jpg\")",
$(SpanElement.class).id(OCTOPUSS_ID)
.getCssValue("background-image"));
"url(\"" + getRootURL() + "/octopuss.jpg\")",
$(SpanElement.class).id(OCTOPUSS_ID)
.getCssValue("background-image"));

getDriver().get(getRootURL() + "/path/test/path/monarch-butterfly.jpg");
Assert.assertFalse("webapp resource should be served",
driver.getPageSource().contains("HTTP ERROR 404 Not Found"));
driver.getPageSource().contains("HTTP ERROR 404 Not Found"));

getDriver().get(getRootURL() + "/octopuss.jpg");
Assert.assertFalse("root resource should be served",
driver.getPageSource().contains("HTTP ERROR 404 Not Found"));
driver.getPageSource().contains("HTTP ERROR 404 Not Found"));
}

@Override
Expand Down

0 comments on commit 9b25ea8

Please sign in to comment.