<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Andrew Arhangelski</title>
    <description>The latest articles on DEV Community by Andrew Arhangelski (@andrew_arhangelski).</description>
    <link>https://dev.to/andrew_arhangelski</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2289559%2F44ec77c8-2506-4281-ac81-ba8be9849f37.png</url>
      <title>DEV Community: Andrew Arhangelski</title>
      <link>https://dev.to/andrew_arhangelski</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andrew_arhangelski"/>
    <language>en</language>
    <item>
      <title>Building an Accessible Front End: A Journey Towards Inclusive Web Design</title>
      <dc:creator>Andrew Arhangelski</dc:creator>
      <pubDate>Fri, 06 Dec 2024 17:07:05 +0000</pubDate>
      <link>https://dev.to/andrew_arhangelski/building-an-accessible-front-end-a-journey-towards-inclusive-web-design-4dn8</link>
      <guid>https://dev.to/andrew_arhangelski/building-an-accessible-front-end-a-journey-towards-inclusive-web-design-4dn8</guid>
      <description>&lt;p&gt;Creating an accessible front end is not just about meeting legal requirements or checking off boxes; it's about making sure every user can fully engage with and enjoy our applications. Accessibility empowers individuals with diverse needs, whether they’re navigating via screen readers, keyboards, or assistive devices. Here’s a deeper dive into our journey and approach to embedding accessibility in every phase of front-end development.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frax91oj8o5drh99keqb9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frax91oj8o5drh99keqb9.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessibility Starts with Design
&lt;/h2&gt;

&lt;p&gt;Accessibility isn’t an afterthought—it begins at the design stage, where choices around fonts, colors, and layout have a profound impact on usability. Often, there’s a temptation to make text subtle and “blend in,” like 4 pt light gray text on a white background. This might create a clean, minimal look, but it also risks making content unreadable, especially for those with visual impairments or color blindness.&lt;/p&gt;

&lt;p&gt;By prioritizing high-contrast text, readable font sizes, and a clear visual hierarchy, we make content accessible from the start. Designers are encouraged to think beyond aesthetics and ask: How will this be perceived by someone with low vision? Can everyone read and understand this content, regardless of their abilities?&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure is Fundamental
&lt;/h2&gt;

&lt;p&gt;A well-structured webpage doesn’t just benefit screen reader users; it helps everyone. Whether it’s someone navigating a webpage for the first time, a visually impaired person using a screen reader, or a user relying on keyboard navigation, proper structure offers clarity. Using semantic HTML elements like &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt; helps convey content relationships, ensuring users understand the flow of information.&lt;/p&gt;

&lt;p&gt;To illustrate, think of a structured webpage as resembling an old newspaper or a scientific document. Each section has headings, main text, and subheadings to guide readers through the information. When done right, even if we strip away all styling, the structure should still convey the page’s hierarchy, allowing users to understand and navigate content intuitively.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdvn7qphh66oxe422kyqa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdvn7qphh66oxe422kyqa.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Consistent HTML Flow and Responsive Design
&lt;/h2&gt;

&lt;p&gt;Today, we access content on screens of all sizes—desktop monitors, laptops, tablets, and phones. Responsive design ensures our applications look good across devices, but it’s also a core part of accessibility. A consistent HTML flow, from top to bottom and left to right, guarantees that users can navigate predictably, regardless of screen size.&lt;/p&gt;

&lt;p&gt;We design our pages to adapt fluidly, so users experience a logical layout that’s easy to follow, even when the screen size changes. This predictability ensures that all users, whether they’re on a smartphone or a desktop, have a consistent and accessible experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkhhexy3eimf07g6ursi2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkhhexy3eimf07g6ursi2.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Logical Heading Hierarchy
&lt;/h2&gt;

&lt;p&gt;Clear heading structure enhances accessibility by helping users and assistive technologies like screen readers interpret page organization. By using a single &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; tag for the main page heading and organizing subheadings in a logical order (&lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;h3&amp;gt;&lt;/code&gt;, etc.), we create a hierarchy that screen readers and search engines alike can understand.&lt;/p&gt;

&lt;p&gt;This structure enables screen reader users to navigate quickly between sections, skipping to content they’re most interested in. It’s a simple yet powerful way to make our applications easier to use and understand. Well-structured headings are a roadmap for the content, guiding users intuitively.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fazd8lwmncpgdd6zotbrp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fazd8lwmncpgdd6zotbrp.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Keyboard Accessibility: The Backbone of Interaction
&lt;/h2&gt;

&lt;p&gt;Keyboard navigation is one of the most important facets of accessibility, allowing users to perform every task on a webpage without needing a mouse. For individuals with motor impairments or those who rely on screen readers, this isn’t optional—it’s essential.&lt;/p&gt;

&lt;p&gt;We design our interfaces so users can select options, toggle buttons, close modals, and interact with every element via the keyboard alone. Keyboard navigation can solve up to 80% of accessibility issues, as it ensures that every element on the page is accessible. This simple step brings us closer to a fully inclusive web experience, benefiting all users.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftd19r0k65mjtrcsbqxfx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftd19r0k65mjtrcsbqxfx.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Visible Focus States: Essential for Orientation
&lt;/h2&gt;

&lt;p&gt;A visible focus indicator is a critical part of keyboard accessibility, showing users where they are on the page at any given moment. In the past, there were trends to hide focus outlines, as they were seen as unattractive. However, this outline serves as a “cursor” for keyboard and screen reader users, providing orientation as they tab through interactive elements.&lt;/p&gt;

&lt;p&gt;Without a visible focus state, users can easily become disoriented and frustrated. By embracing this accessibility feature, we ensure that all users can confidently navigate through our application, knowing exactly where they are in the interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx61bsn61up5e93l5gm59.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx61bsn61up5e93l5gm59.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Role of Invisible Markup: Enhancing Semantic Clarity
&lt;/h2&gt;

&lt;p&gt;Invisible markup is all about using semantic HTML and ARIA attributes to enhance the experience for screen reader users. It’s more than just adding alt attributes or using &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; tags — it’s about making sure the web page structure is clear to assistive technologies.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sections should be linked to headers, creating a logical flow for screen readers.&lt;/li&gt;
&lt;li&gt;Tooltips should be connected to the relevant button or icon, so users have context.&lt;/li&gt;
&lt;li&gt;Lists should be marked as &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt; lists, even if they’re just styled to look like something else.&lt;/li&gt;
&lt;li&gt;Tables should use proper &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; tags, with &lt;code&gt;&amp;lt;th&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;td&amp;gt;&lt;/code&gt; cells defined, so screen readers can convey table information accurately.&lt;/li&gt;
&lt;li&gt;Invisible markup, such as ARIA roles, labels, and landmarks, enables assistive technologies to navigate a page seamlessly, providing valuable context for users. This invisible layer of structure makes a profound difference in how content is experienced by those who rely on screen readers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjqfhg2u5dfz3r92kidn8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjqfhg2u5dfz3r92kidn8.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing with Screen Readers
&lt;/h2&gt;

&lt;p&gt;Testing with screen readers is essential to truly understand the user experience of visually impaired individuals. On a Mac, VoiceOver provides built-in functionality to simulate this experience. By navigating using VoiceOver, we can observe how the application communicates structure and content to the user.&lt;/p&gt;

&lt;p&gt;When testing, we can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate landmarks to quickly reach different sections, such as headers or footers.&lt;/li&gt;
&lt;li&gt;Explore the hierarchy by tabbing through headings to observe how they guide users.&lt;/li&gt;
&lt;li&gt;Navigate tables by moving through cells, ensuring the data makes sense sequentially.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using a screen reader emphasizes the importance of accessible design decisions, from proper HTML structure to clearly linked elements. This hands-on testing is a valuable part of our accessibility toolkit, allowing us to see our work through the lens of users with different abilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessibility is a Continuous Journey
&lt;/h2&gt;

&lt;p&gt;Accessibility isn’t a destination—it’s an ongoing commitment. By embedding these practices into our design and development process, we’re working to make the web a more inclusive space where everyone can participate fully. From initial design choices to development best practices and thorough testing, each step brings us closer to a universally accessible web.&lt;/p&gt;

&lt;p&gt;Let’s keep pushing forward, designing, developing, and testing with accessibility as a priority. Together, we can build digital experiences that are truly inclusive and welcoming to all.&lt;/p&gt;




&lt;p&gt;Illustrations were designed by Freepik &lt;a href="http://www.freepik.com" rel="noopener noreferrer"&gt;www.freepik.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>a11y</category>
      <category>web</category>
      <category>html</category>
    </item>
    <item>
      <title>Running Enzyme Tests in React 18: Our Success Story.</title>
      <dc:creator>Andrew Arhangelski</dc:creator>
      <pubDate>Sun, 27 Oct 2024 23:57:25 +0000</pubDate>
      <link>https://dev.to/andrew_arhangelski/how-we-have-managed-to-run-enzyme-tests-with-react-18-app-1f2e</link>
      <guid>https://dev.to/andrew_arhangelski/how-we-have-managed-to-run-enzyme-tests-with-react-18-app-1f2e</guid>
      <description>&lt;p&gt;Like many other companies with mature software, we found ourselves at a crossroads with our React application. The app, initially developed in early 2019, was built with React 16 and used &lt;a href="https://github.com/enzymejs/enzyme" rel="noopener noreferrer"&gt;Enzyme &lt;/a&gt;for unit testing. Over the past five years, the app grew, evolved, gained new features, and went though minor and major refactorings. Obviously, as responsible engineers we always maintained unit test coverage around 70-80%. However, our React version had remained unchanged.&lt;/p&gt;

&lt;p&gt;By the end of 2024, it became clear that we couldn't delay the upgrade to React 18 any longer. But we faced a challenge: despite gradually adopting &lt;a href="https://testing-library.com/docs/react-testing-library/intro/" rel="noopener noreferrer"&gt;React Testing Library&lt;/a&gt; starting in 2021, we still had around 500 tests written with Enzyme. Unfortunately, enzyme-adapter-react-16 had been abandoned a while ago, and changes in React 18 engine made it impossible to use Enzyme at all.&lt;/p&gt;

&lt;p&gt;We began creating tickets to refactor those Enzyme-based tests to RTL, but quickly realized that given our limited number of engineers, plus our ongoing business and maintenance obligations, rewriting all the tests in a reasonable time frame simply wasn't feasible.&lt;/p&gt;

&lt;p&gt;We decided to explore a different solution: running two versions of React in our application. React 18 would be used for development and RTL unit tests, while React 16 would be retained exclusively for the Enzyme-based tests. This approach allowed us to upgrade without immediately refactoring all of our tests, buying us the time we needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step #1: Two React versions
&lt;/h2&gt;

&lt;p&gt;The first step was to configure our app to install both React versions. Fortunately, modern npm supports this kind of setup through &lt;a href="https://docs.npmjs.com/cli/v10/using-npm/package-spec#aliases" rel="noopener noreferrer"&gt;aliasing&lt;/a&gt;. &lt;br&gt;
We added the following aliases to our &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"react-16": "npm:react@16.13.0",
"react-dom-16": "npm:react-dom@16.13.0"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step #2: Identifying Enzyme Tests
&lt;/h2&gt;

&lt;p&gt;Next, we needed to identify all the files using Enzyme. We did this by searching for files containing &lt;code&gt;import { mount, shallow } from 'enzyme';&lt;/code&gt; and then renaming those files to use the &lt;code&gt;.enzyme.spec.js&lt;/code&gt; extension. This made it easier to differentiate them from the RTL-based tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step #3: Configuring Jest to Run Two Projects
&lt;/h2&gt;

&lt;p&gt;To handle both sets of tests, we configured Jest to run two separate projects—one for RTL and one for Enzyme. Below is our &lt;code&gt;jest.config.js setup&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  ...commonConfig,
  projects: [
    {
      displayName: 'R16 ENZYME - CONVERT ME ASAP!',
      testMatch: ['**/*.enzyme.spec.js'], // Only match enzyme-specific tests
      moduleNameMapper: {
        '^react(/.*)?$': 'react-16$1', // Map to old React 16 for Enzyme tests
        '^react-dom(/.*)?$': 'react-dom-16$1', // Map to old React-DOM 16 for Enzyme tests
      },
      setupFiles: ['&amp;lt;rootDir&amp;gt;/enzyme.config.js'],
      setupFilesAfterEnv: ['&amp;lt;rootDir&amp;gt;/jest-setup-enzyme.js'],
      snapshotSerializers: ['enzyme-to-json/serializer'],
      ...otherConfigs,
    },
    {
      displayName: 'R18 RTL',
      testMatch: ['**/*.spec.js', '**/*.spec.jsx'], // Match other test files
      testPathIgnorePatterns: [
        '\\.enzyme\\.spec\.js$', // Ignore Enzyme tests in this configuration
      ],
      setupFilesAfterEnv: ['&amp;lt;rootDir&amp;gt;/jest-setup.js'], // RTL-specific setup
      ...otherConfigs,
    },
  ],
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the React 16 project, we mapped react and react-dom to the aliased versions (react-16 and react-dom-16) in node_modules, ensuring that Jest would run with the Enzyme configuration for the &lt;code&gt;.enzyme.spec.js&lt;/code&gt; files. Meanwhile, in the React 18 project, we used the &lt;code&gt;jest-setup.js&lt;/code&gt; configuration and excluded the Enzyme test files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step #4: Enzyme Configuration
&lt;/h2&gt;

&lt;p&gt;For Enzyme, we used the following &lt;code&gt;enzyme.config.js&lt;/code&gt; file to configure the Enzyme adapter for React 16:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'regenerator-runtime/runtime';
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter() });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This isn't a perfect solution, but it allowed us to postpone the full refactor of 500 unit tests while enabling the upgrade to React 18. By maintaining dual React versions, we unblocked our path forward, striking a balance between immediate progress and technical debt management.&lt;br&gt;
Our journey highlights that sometimes, pragmatic solutions serve as effective stepping stones. We plan to eventually migrate all tests to RTL, but in the meantime, this approach kept us moving without compromising our ability to deliver quality software.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
