Chris Padilla/Blog
My passion project! Posts spanning music, art, software, books, and more. Equal parts journal, sketchbook, mixtape, dev diary, and commonplace book.
- Checkout is a built in GitHub action that will get your current main commit.
- Cypress has their own GitHub action that takes care of setting up your app.
- I had to set
CYPRESS_BASE_URL
to ensure that Cypress was looking for the correct endpoint, and not the localhost config that is set up in my cypress.config.js file. - Cypress reccomends using explicit version numbers for consistency and stability.
- You can chose which browser to test with
browser: chrome
- I'm passing in my build, start, and cypress commands, though this I believe is also implicit with the Cypress GitHub action.
- Load the landing page
- Get all non-mailto links
- Verify each of those links
- Along the way, exclude any edge cases.
- I'm setting the
baseURL
based on my environment. - I have a list of
excludedLinks
due to some scraping edge cases. (LinkedIn, for example, returns a 999 when a bot visits a page) - The real meat: After I extract the
href
attributes, I run through each and check the status with theexpect
method. - Your intake number is random each time.
- Chose your own adventure style interactivity.
- You get hassled if you don't buy a coke!
- Homestarrunner.com was a webshow/game site/really impressive flash developer portfolio, come to think of it!
- Homestuck (then MS Paint Adventures) was a community based-chose-your-own-adventure series (though, I think the community aspect fell off as the series grew)
- Several webcomics used the medium of a web page to hide jokes in the image alt text and even the
mailto
link's subject line!! (Thinking of Dr. McNinja, Nedroid, and Dinosaur Comics to name a few.) - Neopets was a genre of website that was also a game!! You explored the website in the same way you explored a virtual world. Not to mention that it sported it's own virtual economy!
- When using semantic classnames, you are tightly coupling your css with the html structure of your element. The BEM system makes refactoring difficult.
- Naming things is one of the hardest parts of software. Here, you're not naming anything! You're simply styling with utility classes.
- Cascading styles as well as adjusting classnames can add to your css. With tailwind, you're using utility classes to apply the same styles with minimal customization. That makes the css more maintainable
- Similarly, codebases gets bloated with css doing the exact same thing. my
input__wrapper
may be doing the same positioning as mybutton__wrapper
class. - Colocating CSS and HTML (and JS if using React, Vue, etc.), but without the performance hit.
- Integrate code with design standards
- Bring brand cohesion to an app
- Eliminate decision fatigue from having to design on the fly
- Zero Customizability: We built this to strongly enforce consistency for ourselves.
- Pre-Selected Variations: We’ve got accordions in three different colors.
- BYO Theme: We’ll give you a skeleton that loosely achieves the pattern and you apply the styles to your liking.
Major Seven Dreamy Idea
A floaty idea that hasn't quite made it into a full tune yet. 🍃
Running Cypress in CI with GitHub Actions
I recently set this site up with Cypress for a few end-to-end tests.
(An aside: last time I referred to it as an End-to-end test, but on further reflection, we're probably looking more at these being integration tests. There's no major user interaction aside from GET requests. But, I digress in semantics. Chris Coyier puts the subtle differences nicely over on his blog.)
Here's a look at a new link verification test running in Cypress locally:
With the tests now giving me the ever so satisfying All Tests Passed notification, it's time to automate this!
Github Actions
There are many CI/CD solutions and approaches. In fact, this site is already using Vercel's Github App to automatically deploy pushes to master.
For simplicity I'm going to keep that in place, and run Cypress with GitHub Actions to automatically run my tests.
Configuration
All that's needed to add an action is to create a config file in .github/workflows.yml at the root of the repo. Here's what mine looks like:
name: Cypress Tests
on: [push]
jobs:
cypress-run:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
# Install NPM dependencies, cache them correctly
# and run all Cypress tests
- name: Cypress run
uses: cypress-io/github-action@v5.0.5 # use the explicit version number
env:
CYPRESS_BASE_URL: ${{ github.event.deployment_status.target_url }}
with:
browser: chrome
build: npm run build
start: npm start
command: npx cypress run
Stepping through the important parts:
Violà! Tests are now running with each push to master!
Next Steps
As it's currently setup, I'll get an email on failed tests, but Vercel is still picking up the new code and deploying it. Not an ideal solution, but since I'm a small operation here, I'm not in a hurry to add that structure.
But for the day that I do! The next step would be to remove my Vercel GitHub app from the repo. Then, I can add a deploy action as it's outlined in this post on Vercel's repo:
deploy_now:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: deploy
uses: actions/zeit-now@master
env:
ZEIT_TOKEN: ${{ secrets.ZEIT_TOKEN }}
The environment token can be retrieved by following these steps.
Verify Site Links with Cypress
Here I'm continuing to flesh out my Cypress tests. I've had a few blog pages that have been pushed live, but turn up as 404's due to a formatting issue.
Here, I'm writing a script to verify that all the links on my main page, including blog links, all return a 200 status code.
Writing the Test
Here's the code from last time verifying my RSS Feed:
describe('RSS', () => {
it('Loads the feed', () => {
cy.request(`${baseUrl}/api/feed`).then((res) => {
expect(res.status).to.eq(200);
});
});
});
I'm going to continue to use res.status
to verify a 200 response. It's simpler than loading up the page.
To run this, I'll need to:
Here it is in action:
import { BASE_URL, BASE_URL_DEV } from '../../lib/constants';
const baseUrl = process.env.NODE_ENV === 'production' ? BASE_URL : BASE_URL_DEV;
const excludedLinks = ['bandcamp', 'linkedin', 'instagram'];
describe('Test Broken Links', () => {
it('Verify navigation across landing page links', () => {
cy.visit(baseUrl);
cy.get("a:not([href*='mailto:'])").each((linkElm) => {
const linkPath = linkElm.attr('href');
const shouldExclude = excludedLinks.reduce((p, c) => {
if (p || linkPath.includes(c)) {
return true;
}
return false;
}, false);
if (linkPath.length > 0 && !shouldExclude) {
cy.request(linkPath).then((res) => {
expect(res.status).to.eq(200);
});
}
});
});
});
A couple of lines worth pointing out:
From this, Cypress will run through each link and return results like so:
Have a Coke While You Wait?
The other day I was waxing nostalgic for the way websites used the full canvas of web tech to subvert expectations (as one does.)
The website for Tamara Shopsin's LaserWriter II also does a pretty great job at this.
Go take a look before reading ahead!
A few things that made me smile:
And this one is my favorite: You actually have to wait a few seconds before getting to the juicy book details. The website playfully builds anticipation!
On the internet in 2023, that's a pretty big deal! When everything is immediate and served quickly, it's a really special experience to have to sit and wait, not due to loading, but by design.
And best of all, it's not all just for fun and gags! Everything I mentioned above ties in so well with the book. It's referential and matches tone superbly.
Honestly, the website alone sold me on the book. I then loved the book so much that I wrote an album based on it.
A Love Letter to 2000s Websites
Ryan North over at Dinosaur Comics has a fancy new overlay:
So uh have you ever wished you could read Dinosaur Comics but ALSO be reading newly-public-domain Winnie-the-Pooh and Piglet and not-quite-yet-public-domain-but-hopefully-Disney-is-cool-with-it Tigger?? HAVE I GOT AN OVERLAY FOR YOU, MY FRIEND. Thanks to James Thomson for pulling it together!
I remember the first few overlays on the site when they came out! Heck, I remember the contest ran for the custom footers also on Dinosaur Comics dot com!
I just love this sort of thing! Really novel ways of creating unique interactions on the web. Call me an old man (I am 30 now!) but they just don't make them like they used to, do they??
I'll truncate my nostalgia infused griping to these sentence: Social Media apps have made the web more accessible to more people, giving a platform for voices that otherwise didn't have one. Awesome! AND, aesthetically, a minimal approach has overtaken some of the charm from the old internet. Less awesome!
Ok! With that out of my system, here's this — I know that not every website was overlaying Winnie the Pooh on top their comics, I realize I'm remembering selectively.
So let me pivot from complaining to praising some of my favorites:
I think the running thread here is the creative ways folks used the platform of the web. Not just as a way of delivering content the way that Twitter does. But to really squeeze all the juice that's in the web as its own medium.
Put another way, art didn't end at the edge of the canvas.
I'm really happy to have contributed my own piece through AC:NM. A whole visual novel, as a website! Jenn and I very much started the project in this spirit and with inspiration from those older sites. That era of the internet really felt like the wild west where anything was possible.
On to making more quirky sites!
Impression Minus Expression Equals Depression
That equation feels right.
This comes from the legendary Disney animator and teacher Walt Stanchfield (A lead character animator for the Aristocats, to name one.) I've written before about how Walt Describes the curious act of performing with no audience. This equation come in context from his handouts for gesture drawing:
(Here, Walt is talking about the benefits of staying healthy enough to have the energy to create, another juicy point)
You must create. The injunction of life is to create or perish. Good physical and mental conditioning are necessary to do this. Remember this: the creative energy that created the Universe, created you and its creative power is in you now, motivating you, urging you on - always in the direction of creative expression. I have a formula: "Impression minus expression equals depression". This is especially applicable to artists. We have trained ourselves to be impressed (aware) of all the things around us, and in the natural course of our lives those impressions cry out to be expressed - on paper, on canvas, in music, in poetry, in an animated film. So shape up.
Ain't that the truth?
It's still worth the reminder. When you do professionally creative work (like animation or software!) you are still constantly taking in the world and are falling in love with all sorts of things - books, music, stories, and technologies.
The best way to express that love is through getting down to business and making something.
Sketches
After finishing my last sketchbook, I'm on to the next one!
Here are some of my favorite pages from this week:
I'm also going through Andrew Loomis' "Fun With A Pencil". An older style of caricature, but it's been fun to get comfortable with construction! Here are some head potatoes from my first studies:
Debussy - Rêverie
💭
Little snippet from the gorgeous Debussy piece.
Which was — fun fact — played in the final Anthony Hopkins scene in West World Season 1! Alongside a Radiohead string quartet cover, no less!
Terry Pratchett and Real Life Inspirations
It never really occurred to me growing up that I could work in software.
I grew up playing video games and when I finished them, credits would roll. A flood of names would dash across the screen.
My parents explained to me after watching a movie that it took all these people to make a film. And there was a realness to that.
But, with video games - growing up with Nintendo, all the names were Japanese. And developers - unlike firefighters, police officers, and construction workers - don't have as clear an answer to Richard Scarry's question "What do people do all day?". As far as I know - "Well wow, you have to be Japanese to make games!!"
It wasn't until I met living, breathing people that were making a career of working on the web that it clicked. And that's even after I had done it as a hobby since I was a kid!
Pratchett and Inspiration
I mentioned I'm reading Terry Pratchett's biography. I even wrote a bit about how he gains great satisfaction from the cycle of being a reader and writing for readers.
To continue the conversation - sharing things online helps a great deal. Here's further validation. This time, from the angle of the importance of having heroes that feel real.
Pratchett talks about writing fan mail to Tolkien in his biography, but I like this heartfelt clip from From A Slip of the Keyboard: Collected Non-Fiction :
[W]hen I was young I wrote a letter to J.R.R. Tolkien, just as he was becoming extravagantly famous. I think the book that impressed me was Smith of Wootton Major. Mine must have been among hundreds or thousands of letters he received every week. I got a reply. It might have been dictated. For all I know, it might have been typed to a format. But it was signed. He must have had a sackful of letters from every commune and university in the world, written by people whose children are now grown-up and trying to make a normal life while being named Galadriel or Moonchild. It wasn’t as if I’d said a lot. There were no numbered questions. I just said that I’d enjoyed the book very much. And he said thank you. For a moment, it achieved the most basic and treasured of human communications: you are real, and therefore so am I.
Just like my last post, I can't help but think about the internet. How ridiculously lucky are we to have much closer access to artists, writers, developers — all world class?
Close To Home
It's the humanizing element that can solidify the inspiration, though. It's one thing to hear stories of born prodigies, and another to hear stories of people that started from a place closer to home.
Granny Pratchett told young Terry growing up about G. K. Chesterton. She loaned him Chesterton's books, which he ate up and quickly became a fan. Most importantly, though, she told Terry that Chesterton was a former resident of their town Beaconsfield.
[W]hat seemed to have grabbed Terry most firmly in these revelations was the way they located this famous writer on entirely familiar ground – in Beaconsfield, at the same train station where Terry had but recently laid cons on the tracks for passing trains to crush... It brought with it the realization that, for all that one might very easily form grander ideas about them, authors were flesh and blood and moved among us... And if that were the case, then perhaps it wasn't so outlandish, in the long run, to believe that one might oneself even become an author.
I think we all have stories like this. Some of us may even be luckier - our teachers were this living, breathing validation that what you dream of doing can be done by you.
A similar sentiment from my last post: It's wildly important for you to share your work online. Maybe, even, it's just as important that you do the work you're called to do period. Even if you're not on as global a scale as a published author. For many of us, it's the section-mates in band, the english teachers, the supervisor at work, or even the friends we know from growing up that help solidify dreams into genuine possibilities.
Not to mention the impact you could have, just by sending an email.
Where Does Tailwind Fit In Your App?
If you follow Brad Frost's brilliant atomic model for design systems, Tailwind is at the atomic level.
Tailwind is such an interesting paradigm shift from the typical approach to CSS. I'm still early into it, but I can say I'm starting to see where it shines.
We're in a prototyping phase of implementing a new design system. We're reaching for tailwind to streamline a landing page design and simultaneously flesh out the reusable points of our system — fonts, color, spacing, and the like.
We're bringing this in, though, to a full blown full stack application that's already using styled components for one portion and SCSS for another.
So that's where the question comes from - among all that, where does Tailwind fit? What problem is it really solving?
Tailwind Pros
Once you get past the funny approach to using it, here are the pros, some pulled from Tailwind's docs:
Not to mention, of course, that just like CSS custom properties, it's a way of working within a design system. Once you have your customizations set, spacing, colors, and breakpoints are all baked in to these utility classes.
One nice feature that's not mentioned right out the gate is that you can inline your psuedo-classes, as well. Here's an example from the docs:
<button class="bg-violet-500 hover:bg-violet-600 active:bg-violet-700 focus:outline-none focus:ring focus:ring-violet-300 ...">
Save changes
</button>
It's Atomic, not Molecular
Early on, we came across this issue:
<div class="mt-3 flex -space-x-2 overflow-hidden">
<img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1491528323818-fdd1faba62cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
<img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1550525811-e5869dd03032?ixlib=rb-1.2.1&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
<img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2.25&w=256&h=256&q=80" alt=""/>
<img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
<img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1517365830460-955ce3ccd263?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
</div>
Lots of repeating styles. I assumed there would be a way to component-ise this through Tailwind. They provide it as an option through the @apply
directive on a custom class. However, it's largely not recommended to do this.
The docs argue that "Hey, this is what React is for!"
So there's a clear delineation from Tailwind fitting anywhere higher than the atomic level - higher than a button or input field.
Tailwind is a powerful design system tool that's serving that very particular, atom-level purpose in your application. Taking the "low level" css writing to a greater abstraction, and solving the same co-location problem that CSS-in-JS solves.
We may end up dropping Tailwind from our project in favor of making our own custom classes, but I'll be interested to try Tailwind out a bit more in personal projects.
What, Why, and How of Design Systems
I'm involved in setting up a new design system on a project. From a high level, I've been taking a look at what that means in a React application.
Really quick, here's a succinct definition: "A design system is a collection of reusable components, guided by clear standards, that can be assembled together to build any number of applications."
The aim of a design system is mainly to:
There's A Spectrum
For most developers, the first thing that comes to mind would be Bootstrap. You get an accordion, you get buttons, some basic layout components, and many other goodies. They integrate with React, or you can use plain HTML and CSS.
Bootstrap, however, is on a spectrum of design systems.
Chris Coyier demonstrates this pretty well through asking "Who are design systems for?". The extremes of the spectrum are based on customizabiliy, according to other, more famouse Chris:
Material UI by Google, for example, pretty rigidly feels like a Google product.
But then, you have the list of "Classless CSS" files that just give you some basic stylings for the html elements. And those are a design system too.
Arguable, the browser defaults for html tags are a design system!
Where To Go on the Spectrum
So how heavy handed a design system is depends on the project and team. And if you're developing your own, it's something that's developed organically over time.
A loose, light design system may need more rigidity as the team and app grow.
Even structurally, your design system will likely have a spectrum of component size. Spanning from Atomic elements to templates and pages, as Brad Frost recommends.
But, likely at the start, a few CSS variables with semantic colors and sizing are a good place to begin.
How To Use and Implement
Routes to take include off-the-shelf open source frameworks, customizing those as you go along, developing a component library — the options are plentiful, but many folks point to starting with a template and building from there.
Dave Rupert, deep in the trenches of design system implementation, actually brings up an interesting point about considering these design systems as "Tools Not Rules." As human beings, we want to stretch our design chops. If you're a front end focused dev, you likely get satisfaction from crafting the design yourself to some extent.
On a smaller project and a small team at the start, it's fairly easy to keep freedom within using a system, I believe.
At the end of the day, similar to a framework, it's meant to suit the user. Your team will decide the frameworks used, to what degree of customization, and even how technically proficient you need to be to use the system.
Pratchett Had Libraries, We Have the Internet
The internet is a special place for people who love to create. Sure, you get access to humanity's entire collective knowledge, online shopping, and memes. But I think the secret sauce of what makes the internet a net positive is in how it nurtures and inspires creative communities.
Before it, there were libraries.
I'm reading Author Terry Pratchett's biography. Growing up, he unsurprisingly was absorbed in books and practically lived in his local library. At an early age, Pratchett was marked as a below average student. Through books and the library, though, his creativity and talents flourished.
From the biography, on how it all began at the library -
And, again, it all threaded back to Beaconsfield Library and those string-tied volumes, pushed across the desk. That this 'twit and dreamer' (Terry's phrase again) who found possibilities for himself in a library went on to become the author of books that themselves ended up in libraries, where they could be found by other twits and dreamers in search of possibilities for themselves... I would maintain that the circularity of this outcome satisfied Terry more lastingly and more deeply than any other of the outcomes of his professional success.
Guilty - these days my greatest influences are the ones I discovered online. Some new, some from growing up. And what drives me forward in continuing to make things is that I'm giving back to that online collection of work.
Of course, the internet is even more empowering because a much wider spectrum of creative work ends up on here.
If you're doing this, if you're writing/drawing/musicing/creating online, thank you. More than likely, you're inspiring someone that just needs a model. Someone doing their thing, showing other people that what they want to make can be made.
Finishing a Sketchbook
I reached a funny spot creatively in September. I was making lots of things, but they were all purely digital. Each day also finished with "well, I'm in the process of making something. Not much to show today, though!" There's something that felt a little incomplete about having large creative projects, but no small ones.
A couple of funny intersections happened. I listened to Austin Kleon talk about the benefits of journaling and I picked up reading a few of my favorite art blogs again.
So to fill the gap, I got inspired to sketch everyday in these guys:
And it's been excellent!
Three months later and I filled the last page of the moleskin!
It's a wildly satisfying feeling — one that's not quite recreated on the internet with paginated content and infinite scroll. A website is never full. But a completed sketchbook is a physical, in-your-hands unit. A way of marking time and space while also messing around!
I love making things digitally. But Just like music, keeping a tactile craft going is all the more warm and satisfying. Playing piano and guitar help balance music production. Writing by hand balances blogging. Sketching in a journal is part of that balance, too!
It's best kept largely private to keep it free, but I'll indulge a little! Here are a few of my favorite pages:
Greensleeves
I know I'm not the only one that keeps Christmas decorations around well into the New Year.
Blog Tags
At the end of the year, I noticed a few threads in my blog. Namely tech articles, but a few categories I want to keep following: Books, Art, and Music.
So I'm creating those buckets through tags.
Several blogs have them, but it's Rach Smith's use of a few main themes that inspired me.
I've heard somewhere that tags largely are more for the author than the reader. How often a visitor filters by tags (or even digs deep in the archive, as Alan Jacobs noted) is pretty minimal.
I think there's still value in saying "Hey, I write about this stuff, here are some thoughts on these things."
But I'll agree, probably it's more for me! When I have a bucket, I like filling it. So, keeping Art and Music buckets will lend to more long term thoughts in those categories, even if this space is largely for technical articles.
Besides, I like the colors.