Archiwum kategorii: CSS

Testing React Hooks With Enzyme and React Testing Library

Post pobrano z: Testing React Hooks With Enzyme and React Testing Library

As you begin to make use of React hooks in your applications, you’ll want to be certain the code you write is nothing short of solid. There’s nothing like shipping buggy code. One way to be certain your code is bug-free is to write tests. And testing React hooks is not much different from how React applications are tested in general.

In this tutorial, we will look at how to do that by making use of a to-do application built with hooks. We’ll cover writing of tests using Ezyme and React Testing Library, both of which are able to do just that. If you’re new to Enzyme, we actually posted about it a little while back showing how it can be used with Jest in React applications. It’s not a bad idea to check that as we dig into testing React hooks.

Here’s what we want to test

A pretty standard to-do component looks something like this:

import React, { useState, useRef } from "react";
const Todo = () => {
  const [todos, setTodos] = useState([
    { id: 1, item: "Fix bugs" },
    { id: 2, item: "Take out the trash" }
  ]);
  const todoRef = useRef();
  const removeTodo = id => {
    setTodos(todos.filter(todo => todo.id !== id));
  };
  const addTodo = data => {
    let id = todos.length + 1;
    setTodos([
      ...todos,
      {
        id,
        item: data
      }
    ]);
  };
  const handleNewTodo = e => {
    e.preventDefault();
    const item = todoRef.current;
    addTodo(item.value);
    item.value = "";
  };
  return (
    <div className="container">
      <div className="row">
        <div className="col-md-6">
          <h2>Add Todo</h2>
        </div>
      </div>
      <form>
        <div className="row">
          <div className="col-md-6">
            <input
              type="text"
              autoFocus
              ref={todoRef}
              placeholder="Enter a task"
              className="form-control"
              data-testid="input"
            />
          </div>
        </div>
        <div className="row">
          <div className="col-md-6">
            <button
              type="submit"
              onClick={handleNewTodo}
              className="btn btn-primary"
            >
              Add Task
            </button>
          </div>
        </div>
      </form>
      <div className="row todo-list">
        <div className="col-md-6">
          <h3>Lists</h3>
          {!todos.length ? (
            <div className="no-task">No task!</div>
          ) : (
            <ul data-testid="todos">
              {todos.map(todo => {
                return (
                  <li key={todo.id}>
                    <div>
                      <span>{todo.item}</span>
                      <button
                        className="btn btn-danger"
                        data-testid="delete-button"
                        onClick={() => removeTodo(todo.id)}
                      >
                        X
                      </button>
                    </div>
                  </li>
                );
              })}
            </ul>
          )}
        </div>
      </div>
    </div>
  );
};
export default Todo; 

Testing with Enzyme

We need to install the packages before we can start testing. Time to fire up the terminal!

npm install --save-dev enzyme enzyme-adapter-16 

Inside the src directory, create a file called setupTests.js. This is what we’ll use to configure Enzyme’s adapter.

import Enzyme from "enzyme";
import Adapter from "enzyme-adapter-react-16";
Enzyme.configure({ adapter: new Adapter() }); 

Now we can start writing our tests! We want to test four things:

  1. That the component renders
  2. That the initial to-dos get displayed when it renders
  3. That we can create a new to-do and get back three others
  4. That we can delete one of the initial to-dos and have only one to-do left

In your src directory, create a folder called __tests__ and create the file where you’ll write your Todo component’s tests in it. Let’s call that file Todo.test.js.

With that done, we can import the packages we need and create a describe block where we’ll fill in our tests.

import React from "react";
import { shallow, mount } from "enzyme";
import Todo from "../Todo";

describe("Todo", () => {
  // Tests will go here using `it` blocks
});

Test 1: The component renders

For this, we’ll make use of shallow render. Shallow rendering allows us to check if the render method of the component gets called — that’s what we want to confirm here because that’s the proof we need that the component renders.

it("renders", () => {
  shallow(<Todo />);
});

Test 2: Initial to-dos get displayed

Here is where we’ll make use of the mount method, which allows us to go deeper than what shallow gives us. That way, we can check the length of the to-do items.

it("displays initial to-dos", () => {
  const wrapper = mount(<Todo />);
  expect(wrapper.find("li")).toHaveLength(2);
});

Test 3: We can create a new to-do and get back three others

Let’s think about the process involved in creating a new to-do:

  1. The user enters a value into the input field.
  2. The user clicks the submit button.
  3. We get a total of three to-do items, where the third is the newly created one.
it("adds a new item", () => {
  const wrapper = mount(<Todo />);
  wrapper.find("input").instance().value = "Fix failing test";
  expect(wrapper.find("input").instance().value).toEqual("Fix failing test");
  wrapper.find('[type="submit"]').simulate("click");
  expect(wrapper.find("li")).toHaveLength(3);
  expect(
    wrapper
      .find("li div span")
      .last()
      .text()
  ).toEqual("Fix failing test");
});

We mount the component then we make use of find() and instance() methods to set the value of the input field. We assert that the value of the input field is set to “Fix failing test” before going further to simulate a click event, which should add the new item to the to-do list.

We finally assert that we have three items on the list and that the third item is equal to the one we created.

Test 4: We can delete one of the initial to-dos and have only one to-do left

it("removes an item", () => {
  const wrapper = mount(<Todo />);
  wrapper
    .find("li button")
    .first()
    .simulate("click");
  expect(wrapper.find("li")).toHaveLength(1);
  expect(wrapper.find("li span").map(item => item.text())).toEqual([
    "Take out the trash"
  ]);
});

In this scenario, we return the to-do with a simulated click event on the first item. It’s expected that this will call the removeTodo() method, which should delete the item that was clicked. Then we’re checking the numbers of items we have, and the value of the one that gets returned.

The source code for these four tests are here on GitHub for you to check out.

Testing With react-testing-library

We’ll write three tests for this:

  1. That the initial to-do renders
  2. That we can add a new to-do
  3. That we can delete a to-do

Let’s start by installing the packages we need:

npm install --save-dev @testing-library/jest-dom @testing-library/react

Next, we can import the packages and files:

import React from "react";
import { render, fireEvent } from "@testing-library/react";
import Todo from "../Todo";
import "@testing-library/jest-dom/extend-expect";

test("Todo", () => {
  // Tests go here
}

Test 1: The initial to-do renders

We’ll write our tests in a test block. The first test will look like this:

it("displays initial to-dos", () => {
  const { getByTestId } = render(<Todo />);
  const todos = getByTestId("todos");
  expect(todos.children.length).toBe(2);
});

What’s happening here? We’re making use of getTestId to return the node of the element where data-testid matches the one that was passed to the method. That’s the <ul> element in this case. Then, we’re checking that it has a total of two children (each child being a <li> element inside the unordered list). This will pass as the initial to-do is equal to two.

Test 2: We can add a new to-do

We’re also making use of getTestById here to return the node that matches the argument we’re passing in.

it("adds a new to-do", () => {
  const { getByTestId, getByText } = render(<Todo />);
  const input = getByTestId("input");
  const todos = getByTestId("todos");
  input.value = "Fix failing tests";
  fireEvent.click(getByText("Add Task"));
  expect(todos.children.length).toBe(3);
});

We use getByTestId to return the input field and the ul element like we did before. To simulate a click event that adds a new to-do item, we’re using fireEvent.click() and passing in the getByText() method, which returns the node whose text matches the argument we passed. From there, we can then check to see the length of the to-dos by checking the length of the children array.

Test 3: We can delete a to-do

This will look a little like what we did a little earlier:

it("deletes a to-do", () => {
  const { getAllByTestId, getByTestId } = render(<Todo />);
  const todos = getByTestId("todos");
  const deleteButton = getAllByTestId("delete-button");
  const first = deleteButton[0];
  fireEvent.click(first);
  expect(todos.children.length).toBe(1);
});

We’re making use of getAllByTestId to return the nodes of the delete button. Since we only want to delete one item, we fire a click event on the first item in the collection, which should delete the first to-do. This should then make the length of todos children equal to one.

These tests are also available on GitHub.

Linting

There are two lint rules to abide by when working with hooks:

Rule 1: Call hooks at the top level

…as opposed to inside conditionals, loops or nested functions.

// Don't do this!
if (Math.random() > 0.5) {
  const [invalid, updateInvalid] = useState(false);
}

This goes against the first rule. According to the official documentation, React depends on the order in which hooks are called to associate state and the corresponding useState call. This code breaks the order as the hook will only be called if the conditions are true.

This also applies to useEffect and other hooks. Check out the documentation for more details.

Rule 2: Call hooks from React functional components

Hooks are meant to be used in React functional components — not in React’s class component or a JavaScript function.

We’ve basically covered what not to do when it comes to linting. We can avoid these missteps with an npm package that specifically enforces these rules.

npm install eslint-plugin-react-hooks --save-dev

Here’s what we add to the package’s configuration file to make it do its thing:

{
  "plugins": [
    // ...
    "react-hooks"
  ],
  "rules": {
    // ...
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn"
  }
}

If you are making use of Create React App, then you should know that the package supports the lint plugin out of the box as of v3.0.0.

Go forth and write solid React code!

React hooks are equally prone to error as anything else in your application and you’re gonna want to ensure that you use them well. As we just saw, there’s a couple of ways we can go about it. Whether you use Enzyme or You can either make use of enzyme or React Testing Library to write tests is totally up to you. Either way, try making use of linting as you go, and no doubt, you’ll be glad you did.

The post Testing React Hooks With Enzyme and React Testing Library appeared first on CSS-Tricks.

We are Programmers

Post pobrano z: We are Programmers

Building websites is programming. Writing HTML and CSS is programming. I am a programmer, and if you’re here, reading CSS-Tricks, chances are you’re a programmer, too.

The thing is, the details in programming layout with CSS are different, for example, than the details in programming API endpoints with Ruby. Or machine learning with Python. Or programming a browser engine with C++.

But those differences are details! A lot of details, but still… details. It’s all programming.

I see programmers like this:

An illustration of three scenes, each with a monsters doing a different looking puzzle. In each scene, the moster is labeled as a programmer, and the puzzle is labeled as the programming language. The first scene is C++, the second JavaScript, and the third, Python.

Where do HTML and CSS fit into this weird and cute universe? What is it to program user interface on the web?

Programming boxes, I like to say. Everything is a box, and as HTML/CSS programmers, we program boxes within the domain of the browser. Like this:

Another illustration with a scene where a monster is working on a puzzle, but this puzzle is clearly made of layers of boxes. It is inside a blue square that is labeled 'Browser', and the monster doing the puzzle is very cute with three eyes. It is labeled Box Programmer.

Cute. So?

So…I believe that we, both as individual programmers and together, as the web slice of the tech industry, need to arrive at a more holistic and inclusive understanding of what it means to be a programmer. This outlook not only makes tech a more welcoming place, but it makes us programmers more powerful and more adaptable.

To me – well, me in 2019 – programming is writing1 instructions for computers that other programmers, such as your future self, are able to read and maintain. As programmer, I am confident that, once I know one language well, I can learn another one2. At the end of the day, it’s all made of the same stuff.

And yet…

I have been a programmer in this sense for around eight years, but up until about two years ago, I didn’t see myself as one. In fact, I was actively opposed to calling myself a programmer, and in recent times I’ve heard the same sentiment from others. Why, exactly? Is this a reaction to the „not real programming” phenomenon? Is that still happening? What are the impacts? What were the impacts, for me and for others?

Yes, I know 'gatekeeping’ – that is, the self-inflating exclusion of others from a community or identity – is a thing, and that some people are just jerks, but I think there is more to this story.

So, what’s interesting to me3 about building websites this year? Talking to others who build websites4 and beginning the process of answering these burning questions.


  1. I highly recommend reading Programming is writing is programming, a post and research paper by Felienne. ↩
  2. Box programmers: Do they know things? What do they know? Let’s find out!! In 2020, my goal is to learn learn Rust, a low-level programming language similar to C++. Correction: my goal is to start learning Rust – that is more than a one year undertaking. Why Rust? Keep an eye on my blog, I’ll write more about this soon enough. ↩
  3. It was hard to choose what to write about for this post! I’m interested in a lot of things, specifically unit testing CSS, my job as a Design Engineer, and exploring/sharing more about CSS algorithms.
  4. What do you think, CSS-Tricks reader? Do you call yourself a programmer? Why, or why not? Have you experienced this „not real programming” phenomenon? How did it impact you? Feel free to write me a Twitter message or send me an email.

The post We are Programmers appeared first on CSS-Tricks.

The New Good Ol’ Days

Post pobrano z: The New Good Ol’ Days

Eighteen years into this game, I love to reminisce back to the good ol’ days of the early to mid-2000s when there was an explosion of creativity on the web. It felt fresh and unbridled, with boundaries expected to be pushed at every turn, and they were. This was mainly down to one thing, the thing of nightmares to some, Flash! It, of course, had some big inherent flaws, but love it or hate it, certainly helped pave the way for what we expected from the open web. Sure, it was probably a more drawn-out process than we’d hoped for, but with some savage new advancements made over the last few years, I now feel that things are really starting to get proper juicy.

Several things come to mind that get me excited these days in designing and developing for the web, some widely adopted now like SVG (even though technically old) and WebGL animation, which draw some obvious parallels to the Flash era. Certainly, CSS Grid stood up and made itself known, shouting from the parapets about how the shackles of layout are now a thing of the past. Kudos to awesome people like Rachel Andrew and Jen Simmons for their serious efforts in educating us mere mortals in this area, helping make the learning curve and adoption that bit more palatable and accessible.

Looking around today you can see how advancements like Grid have helped elevate the rise of more asymmetric layouts, with design styles like Brutalism design going through a bit of a trend over the last year or so. But over time it felt as though typography might have taken the back seat a tad with all the other successes happening in pushing the web forward. Now enter variable fonts 🥳

Variable fonts have certainly piqued my interest this past year or so. Not only do they give us the obvious boost in performance with fewer https requests and smaller sizes compared to the bundles of web fonts we all inject into our pages, but we also gain more control over typography in terms of readability and accessibility. Say goodbye to cheekily adding muddy sacrificial faux bold or italic styles to our CSS!

Taking this further, I feel that variable fonts have really unlocked the door to new creative possibilities that we’re only just scratching the surface of. Having the ability to interpolate between different values of the axes just screams out for animation. We have the standardized set of 5 registered axes like font-weight, font-stretch, font-style, etc. which are straight forward enough to appreciate, but when it comes to custom axes via font-variation-settings, things start getting crazy and fun. Type designers can use the interpolation in custom axes to create some really off the wall things beyond, well… text. Just check out Typearture’s fab variable font experiments to see what I mean.

A few months back I was privileged to be invited to experiment with and test Greensock’s newly released GSAP 3, which I’m also most definitely excited about. It boasts a new simplified API and 50+ new features, yet is only about half the file size as the previous version. This is currently my catnip though: layering GSAP on top of variable fonts in CodePen to create some lovely kinetic typography in the DOM. This kind of magic, until now I guess, has been more attributed to WebGL, Processing and After Effects. Now, throw some GSAP plugins on top again, and you can definitely create some very cool and unique stuff. I would suggest, however, that you use this new creative power of animating variable fonts in whichever way you do it sparingly, as reflow could become an issue with jank.

I’m excited to see what people will create using variable fonts over the next year as it becomes more widely adopted. Not just limited to typographic treatments in layouts, but also in terms of animation and micro-interactions. It looks like a big undertaking for designers in creating such fonts, but credit to them. I’m sure we’ll be all the more appreciative. Thanks in advance type designers!

The post The New Good Ol’ Days appeared first on CSS-Tricks.

Growing Accessibility Conversations

Post pobrano z: Growing Accessibility Conversations

I started this year on a new path at Knowbility — to help people and organizations create accessible content and apps. But what was exciting and helped motivate me more were two things:

  1. WebAIM’s Accessibility Analysis of One Million Page Homepages. With over 97% of sites having WCAG failure of some kind, it’s a stinging indictment on our industry. There’s a lot of work to be done — that means outreach and education, helping other developers incorporate accessibility into their workflows, coding pull requests with accessibility fixes, making certain components for design systems are accessible and much more.
  2. The Supreme Court of the United States rejecting Domino’s appeal. The Supreme Court leaves the Ninth Circuit federal appeals court’s ruling, which means that people with disabilities who have trouble with sites or apps that are not accessible can bring claims under the Americans with Disabilities Act (ADA). This result means that organizations can’t kick the proverbial can down the road for making their apps and products accessible.

In regards to the One Million Pages, I noticed that web designers and developers outside of accessibility circles discussing accessibility with a sustained focus I hadn’t witnessed before.

And I would have conversations with people outside web design and development altogether about accessibility due to this court case alone. Companies and organizations were watching it very closely.

This added increased awareness from both WebAIM’s report and the Domino’s appeal has helped fuel the discussion, making it easier to keep the conversation going to make digital accessible to all.

The post Growing Accessibility Conversations appeared first on CSS-Tricks.

Everything and Nothing

Post pobrano z: Everything and Nothing

I’ve been thinking about the question for a solid month now. What about building websites has you interested this year? The question pervaded my solitary thoughts and played in the background during my conversations. I’d love to just tell you the answer I’ve come to, but the more interesting part was my thought journey in getting there.

I jumped at the opportunity to write up my thoughts on this because in general, I am delighted to dive into a conversation about anything that gets me excited. Writing, though, is heavy with irony in my life. There are so many exciting things that I’d love to write about, but I never get asked to write about them. That is of course, until I do, and my mind goes blank.

Even when I properly sat down, cleared my desk, and got out a fresh notebook out to brainstorm and reflect… I still couldn’t really come up with an answer. It worried me.

I thought that maybe my answer would be too meta. Or maybe I couldn’t really notice the thing I’m interested in the most because it’s already seamlessly integrated into my workflow? Nonetheless, I started by collecting thoughts by way of the insta-question-answer technique, where you rapid-fire ask yourself a bunch of questions and say the first thing that comes to mind. This is a great technique when you want to get a quick, reasonably honest answer about something. If you can go fast enough, your brain’s first answer is fairly genuine and generally, the one you have, consciously or subconsciously, spent time thinking about. You also have to place an injunction on your rational brain’s inherent desire to veto your real answers (what if someone sees!) and replace them with more polished ones.

Let’s Play: This Year’s Favorites

What’s your favorite song from this year?
Old Town Road. I want more black cowboys wearing yellow to exist. I didn’t realize how much I wanted that to exist until I saw that performance.

What movie did you like the most?
Godzilla: King of the Monsters. Obviously, even though that little girl should have died like 20 times. I know I probably should have said Avengers End Game because that movie was everything but it’s Godzilla. King of the Monsters. So he has to win.

Favorite tech upgrade?
Automating my lights. I was a little behind the curve on this one but it’s been great.

Mobile App?
Kami 2. Super fun to play.

What about building websites has interested you this year?
Um…

My brain shut down. There was no answer, only silence.

I thought of the answers I should want to say. That the increased focus on accessibility is encouraging. That the new edition of Ember feels pretty nice once you get over not having magic anymore. That design systems done right, paired with a framework done right, is pure productivity bliss.

Truth is, I probably could have made any of those answers work, and no one would be the wiser. After all, they are satisfying answers. Deeply satisfying. Years of passion, patience, and persistence is yielding the fruits of our labor. But none of these answers set isInteresting to true for me. So I kept thinking. Surely the answer would come to me if I let it hang around in my sub-conscious a little more.

A week came and went, but there was still nothing.

I started to become a little anxious. What did it mean? Was I burnt out? Was I just not interested in building websites anymore? Have I lost the spark? Maybe I was just not talented enough to write an article like this? Did I say "yes" to the wrong thing? As tempting as it was to crawl into bed under my covers and continue this downward spiral into the endless black hole „what does it all mean”, I decided to make a strong cup of tea and lean on the skills I have developed over the last 20 plus years of building for the web.

Problem Solving Skills

We already have everything we need. There is no need for self-improvement. All these trips that we lay on ourselves—the heavy-duty fearing that we’re bad and hoping that we’re good, the identities that we so dearly cling to, the rage, the jealousy and the addictions of all kinds—never touch our basic wealth. They are like clouds that temporarily block the sun. But all the time our warmth and brilliance are right here. This is who we really are. We are one blink of an eye away from being fully awake.

This quote is from a prominent Zen Buddhist and one that I reach for when I get stuck inside myself. I remind myself that I already know the answer, I just need to use the tools I have to bring it out and let it shine. I needed to trust the process that has worked time and time again for me: slow up, write everything down, and just ship it.

Part 1) Slow Up

I had become so engrossed in the every-day mundane I was missing the inspiration. It’s easy to get bogged down in lines of code, JIRA tickets, and quarterly goals, all the while explaining ad nauseum that developers should reach for semantic HTML first. I recognize the signs now and knew what I needed to do. I needed to slow down to get faster. Sounds counter-intuitive, right? But it’s the same in software engineering: slow is fast. We have proven, time and time again, that when we rush solutions we incur technical debt that we are unlikely to ever repay.

So I took some time to catch my breath and feed my creativity.

I read a book. I watched an interview with an author. I learned from a video series about a standup comedian talking about their process in creating. I sat still and listened to some cello music.

Part 2) Write Everything Down

The next part of my process is to write things down. When creative inspiration is missing, I turn to functional discipline. I have learned that they are the yin and yang of my creative process as a whole. So, I started to make lists. I listed all of the things I have shipped so far this year. I listed all of the conferences where I gave talks and the conferences where I wanted to give talks but didn’t. I wrote down the things that gave me confidence this past year and the things that made me feel like an imposter. I looked at my goals from the start of the year and made a list of the things I’d done for each goal.

Then I started writing a little more, this time in paragraphs. I transcribed one of my talks and took notes on where I would do better next time. I write a review of one of my annual goals and thought a bit more deeply about what motivates and inspires me.

Part 3) Just Ship It

Then it came to me. I knew the answer.

It was nothing, but it was everything.

Nothing specifically about building websites has specifically interested me this year – but I’m still as interested as ever in building them. The answer to „what about building websites has interested you this year” is simply a resounding „Yes”.

Yes, because I still love thinking about design, components, and the perfect information architecture. Yes, because as much as I swear at my code, I keep coming back to it, keep finding new things to love about it, keep feeling energized when that idea just clicks and something great happens. Yes, because despite doing this for 22 years, I still want to get up and do it again tomorrow.

And that’s when I knew that I could just ship it.

The tech of today, the tech of tomorrow

We are at a specific time and place in tech. Those of us who are building for the web have become more aware of how the tech we create effects those around us. We are starting to accept our responsibility for the lines of code that we write, and see that we cannot merely pass the buck to our supervisors and bosses to make ethical decisions. We are demanding more of ourselves, demanding more from the code we write and the systems we use, demanding more from the giants of technology who seek to abdicate responsibility for how their tech is used.

At the same time, we are figuring out how to climb the proverbial mountain together, while recapturing the fun we had back in the days we called ourselves „webmasters”. We are learning to be kinder to ourselves and others. We are figuring out how to make creating for the web easier to learn and to do and we are breaking down the walls that kept far too many people out for too long.

I was watching my son while he was absorbed in lightsaber battles in virtual reality and thinking about how his childhood is so different than mine. The tech I had back then isn’t anything near the tech I have today, and the tech he has today won’t be the tech he has as an adult. What do I imagine that will look like? Even bigger than that, what do I want to help bring into existence?

The truth is, it’s all interesting to me. All of it. I can’t wait to see we do next and I’m so here for it.

The post Everything and Nothing appeared first on CSS-Tricks.

JAMstack CMSs Have Finally Grown Up!

Post pobrano z: JAMstack CMSs Have Finally Grown Up!

This article is based on Brian’s presentation at Connect.Tech 2019. Slides with speaker notes from that presentation are available to download.

In my experience, developers generally find the benefits of the JAMstack easy to comprehend. Sites are faster because the resources are static and served from a CDN. Sites are more secure because there is no framework, application server or database to compromise. Development and deployment can be optimized because all of the pieces that make up the stack are unbundled. And so on.

What can be more difficult for developers to comprehend are the trade-offs that this can often require for the folks who create and edit content. Traditional, monolithic content management systems have often been ridiculed by developers (yes, even WordPress) who became frustrated trying to bend the tool to their will in order to meet project requirements. But, until recently, the JAMstack largely just passed that burden onto the non-technical content creators and editors.

By developers, for developers

Static site generators (i.e. tools like Jekyll, Hugo and Gatsby) grew enormously in popularity in large part because developers adopted them for projects. They became common solutions for things like blogs, documentation or simple static pages. By and large, these were sites created by developers, maintained by developers and with the content primarily written and edited by developers.

When I first wrote about these tools in a report for O’Reilly in 2015, this is what I said:

Just in case this isn’t already clear, I want to emphasize that static site generators are built for developers. This starts with the development of the site all the way through to adding content. It’s unlikely that non-developers will feel comfortable writing in Markdown with YAML or JSON front matter, which is the metadata contained at the beginning of most static site engine content or files. Nor would non- technical users likely feel comfortable editing YAML or JSON data files.

—Me (Static Site Generators report for O’Reilly 2015)

When, two years later, I wrote a book for O’Reilly on the topic (with my friend Raymond Camden), not too much had changed. There were some tools at the very early stages, including Jekyll Admin and Netlify CMS, but they had not matured to a point that they could realistically compete with the sort of WYSIWYG tooling that content editors were used to in tools like WordPress.

The WordPress editor showing a field for the post title and a text area for the post content.
The WordPress editing experience

By contrast, the editing experience of static CMSs still required an understanding of Markdown and other markup (YAML, Liquid, etc.).

An editing screen in Netlify showing post fields on the left and a preview of the post on the right.
The Netlify CMS editing experience in 2017

Suffice it to say, whatever the technical merits of the architecture at the time, from a content editing standpoint, this was not a toolset that was ready for mainstream adoption.

The awkward teenage years

Over the ensuing two years, a combination of a couple of trends started to make the JAMstack a viable solution for mainstream content sites with non-technical editors. The first was that the static CMS matured into what we now generally refer to as git-based CMS solutions. The second was the rise of the headless, API-first CMS as a solution adopted by enterprises.

Let’s take a look at the first trend… well… first. Netlify CMS, an open-source project from Netlify, is an example of a git-based CMS. A git-based CMS doesn’t store your content, as a traditional CMS would, but it has tools that understand how to edit things like Markdown, YAML, JSON and other formats that make up a JAMstack site. This gives the content editors tools they feel comfortable with, but, behind the scenes, their content changes are simply committed back into the repository, forcing a rebuild of the site. While Netlify CMS is installed on the site itself, other popular git-based CMS options are web-based, including Forestry and DatoCMS.

An editing screen in Netlify from 2017 showing post fields on the left and a preview of the post on the right.
The current editing experience in Netlify CMS

The headless, API-first CMS functions much more like the editing experience in a traditional CMS. It not only offers tools for creating and editing content, but it stores that content. However, it makes that content available to the front end – any front-end – via an API. While not limited to JAMstack in any way, an API-first CMS works well with it because the creation and management of the content is separate from the display of that content on the front end. In addition, many API-first CMSs offer pre-built integrations with some of the most widely used static site generators. Popular API-first options include Contentful and Sanity.

The Contentful admin, showing post fields on the left and post settings on the right.
Contentful

HeadlessCMS.org is a site maintained by Netlify that has a comprehensive list of all the available tools, both git-based and API-first. For a good look at the differences, pros and cons between choosing a git-based versus an API-first CMS, check out this post by Bejamas.

Both git-based and API-first headless CMS options began to give non-technical content editors the tools they needed on the backend to create content. The awkwardness of these „teenage years” comes from the fact that the tooling is still disconnected from the frontend. This makes it difficult to see how changes you’ve made in the backend will impact the frontend until those changes are actually committed to the repo or pushed live via the API. Add in the time cost of a rebuild and you have a less than ideal editing experience where mistakes can more easily make it to the live site.

A Look at the future

So what does the future look like when the JAMstack CMS is finally grown up? Well, we got a good look at this year’s JAMstack_conf_sf. Coincidentally, there were two presentations demonstrating new tools that are bringing the content editing experience to the frontend, letting content editors see what they are changing, how their changes will look and how they will impact the layout of the site.

The first presentation was by Scott Gallant of Forestry. In it, he introduced an new open source projects from Forestry called TinaCMS that brings a WYSIWYG style content editing experience to the frontend of sites that use a git-based CMS and Gatsby or Next.js (both React-based tools).

Animated flow for editing a page on the front end with Tina CMS.
TinaCMS

The second presentation was by Ohad Eder-Pressman of Stackbit (full disclosure: I work as a Developer Advocate for Stackbit) that introduced an upcoming set of tools called Stackbit Live. Stackbit Live is designed to be CMS and static site generator agnostic, while still allowing on-page editing and previewing of a JAMstack site.

Animation of editing a page on the front end with Stackbit Love
Stackbit Live

What both these tools demonstrated is that we’re at a point where a „JAMStack + headless” architecture is a real alternative to a traditional CMS. I believe we’ve reached the tipping point whereby we’re no longer trading a great developer experience for an uncomfortable editing experience for content authors. By 2020, JAMstack CMS will officially be all grown up. 👩🏽‍🎓

The post JAMstack CMSs Have Finally Grown Up! appeared first on CSS-Tricks.

The Amazingly Useful Tools from Yoksel

Post pobrano z: The Amazingly Useful Tools from Yoksel

I find myself web searching for some tool by Yoksel at least every month. I figured I’d list out some of my favorites here in case you aren’t aware of them.

The post The Amazingly Useful Tools from Yoksel appeared first on CSS-Tricks.

How We Perform Frontend Testing on StackPath’s Customer Portal

Post pobrano z: How We Perform Frontend Testing on StackPath’s Customer Portal

Nice post from Thomas Ladd about how their front-end team does testing. The list feels like a nice place to be:

  1. TypeScript – A language, but you’re essentially getting various testing for free (passing the right arguments and types of variables)
  2. Jest – Unit tests. JavaScript functions are doing the right stuff. Works with React.
  3. Cypress – Integration tests. Page loads, do stuff with page, expected things happen in DOM. Thomas says their end-to-end tests (e.g. hitting services) are also done in Cypress with zero mocking of data.

I would think this is reflective of a modern setup making its way across lots of front-end teams. If there is anything to add to it, I’d think visual regression testing (e.g. with a tool like Percy) would be the thing to add.

As an alternative to Cypress, jest-puppeteer is also worth mentioning because (1) Jest is already in use here and (2) Puppeteer is perhaps a more direct way of controlling the browser — no middleman language or Electron or anything.

Thomas even writes that there’s a downside here: too-many-tools:

Not only do we have to know how to write tests in these different tools; we also have to make decisions all the time about which tool to use. Should I write an E2E test covering this functionality or is just writing an integration test fine? Do I need unit tests covering some of these finer-grain details as well?

There is undoubtedly a mental load here that isn’t present if you only have one choice. In general, we start with integration tests as the default and then add on an E2E test if we feel the functionality is particularly critical and backend-dependent.

I’m not sure we’ll ever get to a point where we only have to write one kind of test, but having unit and integration tests share some common language is nice. I’m also theoretically opposite in my conclusion: integration/E2E tests are a better default, since they are closer to reality and prove that a ton is going right in just testing one thing. They should be the default. However, they are also slower and flakier, so sad trombone.

Direct Link to Article — Permalink

The post How We Perform Frontend Testing on StackPath’s Customer Portal appeared first on CSS-Tricks.

Weekly Platform News: Internet Explorer Mode, Speed Report in Search Console, Restricting Notification Prompts

Post pobrano z: Weekly Platform News: Internet Explorer Mode, Speed Report in Search Console, Restricting Notification Prompts

In this week’s roundup: Internet Explorer finds its way into Edge, Google Search Console touts a new speed report, and Firefox gives Facebook’s notification the silent treatment.

Let’s get into the news!

Edge browser with new Internet Explorer mode launches in January

Microsoft expects to release the new Chromium-based Edge browser on January 15, on both Windows and macOS. This browser includes a new Internet Explorer mode that allows Edge to automatically and seamlessly render tabs containing specific legacy content (e.g., a company’s intranet) using Internet Explorer’s engine instead of Edge’s standard engine (Blink).

Here’s a sped-up excerpt from Fred Pullen’s presentation that shows the new Internet Explorer mode in action:

(via Kyle Pflug)

Speed report experimentally available in Google Search Console

The new Speed report in Google’s Search Console shows how your website performs for real-world Chrome users (both on mobile and desktop). Pages that „pass a certain threshold of visits” are categorized into fast, moderate, and slow pages.

Tip: After fixing a speed issue, use the “Validate fix” button to notify Google Search. Google will verify the fix and re-index the pages if the issue is resolved.

(via Google Webmasters)

Facebook’s notification prompt will disappear in Firefox

Firefox will soon start blocking notification prompts on websites that request the notification permission immediately on page load (Facebook does this). Instead of the prompt, a small “speech balloon” icon will be shown in the URL bar.

Websites will still be able to show a notification prompt in Firefox as long as they request permission in response to a user interaction (a click, tap, or key press).

(via Marcos Càceres)

More news…

Read more news in my weekly newsletter for web developers. Pledge as little as $2 per month to get the latest news from me via email every Monday.

More News →

The post Weekly Platform News: Internet Explorer Mode, Speed Report in Search Console, Restricting Notification Prompts appeared first on CSS-Tricks.

Two-Value Display Syntax (and Sometimes Three)

Post pobrano z: Two-Value Display Syntax (and Sometimes Three)

You know the single-value syntax: .thing { display: block; }. The value „block” being a single value. There are lots of single values for display. For example, inline-flex, which is like flex in that it becomse a flex container, but behaves like an inline-level element rather than a block-level element. Somewhat intuitive, but much better served by a two-value system that can apply that same concept more broadly and just as intuitively.

For a deep look, you should read Rachel Andrew’s blog post The two-value syntax of the CSS Display property. The spec is also a decent read, as is this video from Miriam:

This is how it maps in my brain

Choose block or inline, then choose flow, flow-root, flex, grid, or table. If it’s a list-item that’s a third thing.

You essentially pick one from each column to describe the layout you want. So the existing values we use all the time map out something like this:

Another way to think about those two columns I have there is „outside” and „inside” display values. Outside, as in, how it flows with other elements around it. Inside, as in, how layout happens inside those elements.

Can you actually use it?

Not really. Firefox 70 is first out of the gate with it, and there are no other signals for support from Chrome-land or Safari-land that I know about. It’s a great evolution of CSS, but as far as day-to-day usage, it’ll be years out. Something as vital as layout isn’t something you wanna let fail just for this somewhat minor descriptive benefit. Nor is it probably worth the trouble to progressively enhance with @supports and such.

Weirdnesses

  • You can’t block flow because that doesn’t really make sense. It’ll be reset to block flow-root.
  • There is implied shorthand. Like if you inline list-item, that’s really inline flow list-item whereas list-item is block flow list-item. Looks all fairly intuitive.
  • You still use stuff like table-row and table-header-group. Those are single-value deals, as is contents and none.
  • Column one technically includes run-in too, but as far as I know, no browser has ever supported run-in display.
  • Column two technically includes ruby, but I have never understood what that even is.

How we talk about CSS

I like how Rachel ties this change to a more rational mental and teaching model:

… They properly explain the interaction of boxes with other boxes, in terms of whether they are block or inline, plus the behavior of the children. For understanding what display is and does, I think they make for a very useful clarification. As a result, I’ve started to teach display using these two values to help explain what is going on when you change formatting contexts.

It is always exciting to see new features being implemented, I hope that other browsers will also implement these two-value versions soon. And then, in the not too distant future we’ll be able to write CSS in the same way as we now explain it, clearly demonstrating the relationship between boxes and the behavior of their children.

The post Two-Value Display Syntax (and Sometimes Three) appeared first on CSS-Tricks.