Ideas Engineered for Tomorrow
We Engineer Services & Solutions for Your Business Needs
Consulting Services Hire Book Consulting

Accessibility Testing Services in India

WCAG 2.1 and 2.2 audits, keyboard-only traversal and screen reader passes with NVDA, JAWS and VoiceOver, run by an engineering team in India for CTOs, founders and product leaders in the US, UK, Canada, Australia and New Zealand. Accessibility testing services in India are usually bought after a scanner came back green and a real user still could not finish checkout. This page is about the gap between those two facts.

Why Does a Page With Zero axe Errors Still Lock People Out?

Here is the sequence we get called in after, more or less word for word every time. Someone runs Lighthouse. The accessibility score is 96, or 100. A ticket gets closed. Six weeks later a customer writes in to say they cannot place an order using a screen reader, or a procurement team asks for an accessibility conformance report and the honest answer turns out to be that nobody knows.

Both things are true at once. The scanner was not lying, and the site is not usable. A rules engine reads the rendered DOM and checks facts it can decide on its own: does this image have an alt attribute, do these two colours meet a ratio, does this input have an associated label, is this ARIA attribute valid on this role. Those are real checks and they catch real bugs. They are also a thin slice of what makes an interface operable.

Deque, the company that builds axe-core, puts its own automated coverage at somewhere around 57 percent of accessibility issues. That is a vendor figure about a vendor tool and worth treating as such, but it is close to what we measure in practice, and note which direction the vendor is arguing in. The remainder is the part a machine cannot decide. Whether the alt text describes the image or just repeats the filename. Whether the heading structure reflects the actual document. Whether the custom dropdown responds to Arrow Down. Whether focus goes somewhere sensible after the modal closes. Whether an error message is announced at all.

The failure that costs the most is almost never a missing alt attribute. It is a div with a click handler and no role, sitting in the checkout flow, invisible to the keyboard.

WebAIM's annual Million study scans a million home pages and has reported automatically detectable WCAG failures on well over ninety percent of them every year it has run. That number is depressing on its own, and it understates the position, because it counts only what a scanner can see. The manual failures sit underneath it, uncounted.

There is a second reason the score misleads you. The Lighthouse accessibility number is a weighted average of a subset of axe rules, and Google's own documentation says a perfect score does not mean the page is accessible. A page with one heading, one paragraph and no interactive elements scores 100. So does a page where everything works. The score cannot tell the difference between a passing product and an empty one, which makes it a regression signal at best.

WCAG 2.1, WCAG 2.2 and What Level AA Actually Asks For

Almost every contract, RFP and internal policy that mentions accessibility points at WCAG, and almost every one of them says Level AA. Worth knowing what you have signed up to before you scope the testing.

The version question, settled quickly

WCAG 2.1 became a W3C Recommendation in 2018. WCAG 2.2 arrived in 2023 and is backwards compatible: it keeps everything in 2.1, adds nine new success criteria and retires one, the old 4.1.1 Parsing criterion, which had become obsolete because browsers now handle duplicate IDs and malformed markup consistently enough that the check no longer told you anything about accessibility.

So if you meet 2.2 you meet 2.1. Testing against 2.2 and reporting which findings are 2.2-only is the sensible default, because it costs almost nothing extra and it means your report survives the next time a procurement document moves the goalposts. The one case where you deliberately test against 2.1 is when a specific regulation or contract names 2.1 and you need the paper trail to match the wording.

The additions in 2.2 are worth knowing individually because several of them catch modern interface habits. Focus Not Obscured stops a sticky header or a cookie banner covering the element the keyboard just moved to. Target Size (Minimum) sets a floor of 24 by 24 CSS pixels for pointer targets at AA, with exceptions for inline links and cases where spacing compensates. Dragging Movements requires a single-pointer alternative to any drag interaction, which is the criterion that catches kanban boards, sliders, reorderable lists and map controls. Consistent Help asks that help mechanisms stay in the same relative place across pages. Redundant Entry says stop asking for the same information twice in one process. Accessible Authentication rules out cognitive function tests such as transcribing a puzzle or remembering a code, unless an alternative exists.

That last one has teeth. If your login flow depends on solving an image puzzle with no alternative, that is a AA failure under 2.2, and it is not a markup problem. It is a product decision that has to be reversed.

A, AA and AAA, and why nobody targets AAA

Level A is the floor. Fail it and there are people who simply cannot use the feature at all. Keyboard operability, no keyboard traps, form labels, video captions, no content that flashes above the seizure threshold.

Level AA is what regulations and contracts almost always name, and it is where the bulk of real work sits: contrast ratios, resize and reflow, visible focus, error suggestion, status messages, consistent navigation. In WCAG 2.1, A and AA together come to fifty success criteria. WCAG 2.2 adds two at A and four at AA and retires one, so you land in the mid fifties.

Level AAA exists and W3C itself notes that it is not possible to satisfy for all content. The 7:1 contrast requirement rules out most brand palettes. Sign language interpretation for all prerecorded audio is a production budget, not a code change. Pick individual AAA criteria where they suit your audience, and there are good ones. Target Size (Enhanced) at 44 by 44 pixels is worth adopting on mobile whether or not anybody asks. Just do not put AAA in a contract.

What AA looks like when you actually test it

The criteria read as abstractions until you attach them to a screen. In practice, a AA pass on a typical product application means: every interactive element reachable and operable by keyboard in an order that matches the visual layout, with a focus indicator you can see against every background it lands on. Text at 4.5:1 against its background, large text and UI component boundaries at 3:1. The page usable at 320 CSS pixels wide without two-dimensional scrolling, which is the Reflow criterion and is roughly what you get at 400 percent zoom on a 1280 pixel screen. Text spacing overridable without content being clipped. Every form control with a programmatic label, every error identified in text and, where you can, with a suggestion for fixing it. Status messages announced without moving focus. Content that appears on hover dismissable and hoverable. Video captioned, audio described where the visual carries information the narration does not.

None of that is exotic. Most of it is a week of work in a design system and a fortnight of arguing about the focus ring colour.

What an Accessibility Testing Engagement Covers

Not every engagement runs all of this. The scoping conversation sets the order, and the order matters, because a full manual audit of a design system that is about to be replaced is money set on fire.

Inventory before testing

We start by counting templates and journeys, not pages. A catalogue with forty thousand product URLs has one product template. What we need is the list of distinct layouts, the shared component library behind them, and the two or three journeys where a failure has a cost you can name: signup, checkout, the search-to-result path, the account settings page where people cancel.

This is also where we find the pages nobody remembers owning. The legacy help centre on a different stack. The PDF that the entire onboarding depends on. The third-party payment iframe that you cannot change and will have to raise with the vendor.

Automated sweep

axe-core across the inventory, at page level and at component level, with the results deduplicated by rule and by component rather than by URL. A hundred and forty instances of the same unlabelled icon button is one finding about one component, not a hundred and forty tickets. Reports that do not deduplicate are how a team ends up with an eight hundred row spreadsheet that nobody opens.

Manual audit against the criteria

Keyboard traversal of every screen. Focus order and focus visibility. Reading order in the accessibility tree. Heading structure. Screen reader passes on the pairings your users actually run. Zoom and reflow at 400 percent. Text spacing overrides. Contrast checked by eye and by tool, including the states a scanner never sees, which is most of them.

Findings written so a developer can act

Each issue gets: the WCAG criterion and level, a severity based on whether it blocks a task or degrades it, the exact steps and keys to reproduce, the assistive technology and browser pairing, what was announced versus what should have been, a short screen recording with audio, and a code level suggestion rather than a restatement of the criterion. Writing 4.1.2 Name, Role, Value into a ticket and leaving it there is not a finding. It is homework you have set for the engineer.

Remediation support and re-test

Depending on how you want to work, our engineers either fix the components directly in your repository or pair with your team while they do it. Then a verification pass against the register, with each finding marked fixed, partially fixed or rejected with a reason. Rejected is a legitimate outcome. Sometimes the fix is a product change you have decided not to make this quarter, and the register should say so honestly.

Regression protection

The audit is a snapshot. Without a gate, the same bugs come back within two releases. So we wire axe into your pipeline at the component level, add eslint-plugin-jsx-a11y or its equivalent at authoring time, add keyboard interaction tests for the widgets that broke, and add an accessibility section to the definition of done. The gate that works best is the cheapest one: a component cannot merge into the design system without a keyboard test and a documented name and role.

Documentation and handover

The issue register, the test matrix showing which pairings were used on which screens, the component-level patterns we adopted, and an evidence pack you can hand to a procurement team. We produce the audit evidence. Any conformance statement you publish from it is yours to make with your counsel.

The Tools: What Each One Finds and Where It Stops

Every tool below is worth having. None of them is worth trusting alone. The useful skill is knowing which question each one can answer.

axe-core

The open source rules engine from Deque, and the thing most other scanners are quietly running underneath. It is designed to avoid false positives, which is why it stays silent on anything ambiguous rather than guessing. That design choice is exactly why it misses things: if a rule cannot decide, no rule fires.

Where it earns its place is in the pipeline. @axe-core/playwright, cypress-axe and jest-axe let you scan a component in isolation rather than a whole page, which is where the results are actually actionable. Run it against every story in Storybook and you catch a broken component before it reaches forty screens. What it will not tell you: whether focus order matches the visual order, whether your live region announces at the right moment, whether the arrow keys work.

Pa11y and pa11y-ci

A command line runner that can drive either HTML_CodeSniffer or axe. Its value is breadth: point pa11y-ci at a sitemap, get a pass or fail across a few hundred URLs on a schedule, and catch the day somebody deploys a template change that strips labels off every form on the site. Use it for coverage across a large content site. Do not use it as your audit method, and be aware that the HTML_CodeSniffer engine is noisier than axe and will produce warnings that a human has to triage.

Lighthouse

Built into Chrome DevTools and into most CI setups already, running a subset of axe rules and reducing them to a score out of 100. Convenient, and routinely over-read. The score is weighted, it covers fewer rules than a full axe run, and Google's documentation is explicit that 100 does not mean accessible. Treat it as a smoke alarm on a pull request, never as an audit result, and never put the number in a compliance document.

WAVE

WebAIM's browser extension, and the one we reach for when explaining a problem to somebody who is not an engineer. Instead of a list, it draws icons onto the page itself, so a designer can see that the heading they styled as a section title is an h5, or that the contrast failure is on the one button that matters. The structure and order view is genuinely useful for teaching. It is a per-page interactive tool, so it does not belong in CI, and its heading and ARIA views take some interpretation.

Accessibility Insights for Web

Microsoft's tool, and the one most often left out of these lists despite doing something the others do not. FastPass runs the automated checks and then adds a tab stop visualiser that draws the actual focus path on the page as you press Tab, numbered in order. Watching the line jump from the header to the footer and back tells you more in ten seconds than a report does. Its Assessment mode then walks you through the manual checks the automation cannot do, with instructions per criterion, which makes it a decent scaffold for a team learning to audit. There is a Windows version for native applications too.

The ones that fill the gaps

TPGi's Colour Contrast Analyser for sampling colours from anywhere on screen, including gradients, images and video frames where a browser extension cannot reach. ARC Toolkit and the IBM Equal Access Checker as second opinions with different rule sets, useful when you want to know whether a finding is real or a quirk of one engine. The browser's own accessibility tree inspector, in Chrome or Firefox DevTools, which is where you go when you need to know what a control is actually exposed as rather than what the markup suggests. And the screen readers themselves, which are not test tools but are the only source of truth.

One tool category we will not use, and will tell you to remove: overlay widgets. A script injected at runtime cannot know what your image depicts, cannot restructure your headings correctly and cannot turn a div into a keyboard operable control. It changes what the page reports without changing what the page does. The Overlay Fact Sheet documents the practitioner position, and it is signed by a large share of the field including people who use screen readers every day.

The Manual Pass: Keyboard, Focus and Reading Order

The first thing an auditor does is stop using the mouse. Not metaphorically. Hands off it for the whole journey, because the moment you reach for it you have stopped testing.

Keyboard-only traversal is the highest yield hour in the whole engagement, and it is the check almost nobody runs before shipping. Tab forward through the entire flow. Shift+Tab back. Enter and Space on every control. Arrow keys inside every composite widget. Escape on every layer that opens. Then do it again with the browser window at 400 percent zoom, because that is where sticky elements start swallowing focus.

What the keyboard pass finds

Controls that cannot be reached at all, which is usually a div or a span with an onClick and no tabindex, no role and no key handler. Controls that can be reached but not operated, where Enter works and Space does nothing because the element is not a button and nobody added the keydown case. Keyboard traps: a custom date picker or an embedded third-party widget that takes focus and will not give it back, which under 2.1.2 is a Level A failure and in practice means the user has to close the tab.

Then the focus order problems. CSS has made these more common, not less. Flexbox order, grid placement and absolute positioning all let you rearrange what a person sees while the DOM order stays as authored, so the visual layout says left column then right column and Tab goes right, left, right, left. Position absolute is the worst offender because a link parked visually at the top of the page can sit at the bottom of the DOM.

And focus loss. Open a modal, close it, press Tab: where did you land? If focus fell back to the top of the document, a screen reader user has just been sent to the start of the page and has to find their way back. Same bug, worse consequences, when a single page application changes route and focus stays on the link that no longer exists. Route change focus management is the single most common serious defect we find in React, Vue and Angular products, and it is invisible to every scanner.

Focus visibility, which is a design fight

Somewhere in most codebases there is an outline: none rule, added years ago because the default ring was ugly, and never replaced. WCAG 2.1 asks that the focus indicator is visible at AA. WCAG 2.2 adds that it must not be hidden by other content, and offers a stricter appearance criterion at AAA covering size and contrast.

The practical rules we apply: use :focus-visible so mouse users do not see rings they do not need while keyboard users always do. Give the indicator at least 3:1 contrast against the adjacent colour. Test it on every background the control appears on, because a white ring on a white card is technically present and functionally absent. And give it thickness. A one pixel outline on a busy page is not an indicator, it is a rumour.

Reading order in the accessibility tree

Separate check, different failure. Open the accessibility tree in DevTools and read down it as a document. Does it make sense with no styling at all? Are the headings a real outline, or did somebody pick h4 because it was the right size? Is the main navigation inside a nav, the primary content inside a main, and is there a skip link that actually moves focus rather than just moving the viewport? Are the landmarks named where there is more than one of a kind?

Tables are where this collapses fastest. A layout table with no headers reads as a wall of unrelated cells. A data table with th elements but no scope attribute reads inconsistently across screen readers. And a table built out of divs with role attributes bolted on afterwards will announce row and column positions that do not match what is on screen, which is worse than no semantics at all.

Screen Reader Testing, and Why NVDA, JAWS and VoiceOver Disagree

Screen readers are not interchangeable. They implement the same specifications, and then they add heuristics, and the heuristics differ. Something that reads perfectly in one can be silent in another, which is why a single-reader pass gives false confidence in both directions.

NVDA

Free, open source, from NV Access, and the default choice for testing on Windows because anybody on your team can install it this afternoon. It sticks closer to what the markup actually says than JAWS does, which makes it the better diagnostic: if NVDA announces a button with no name, the button genuinely has no accessible name. Pair it with Firefox and with Chrome, since the accessibility APIs behind them differ enough to produce different results on the same page.

The concept that trips up first-time testers is browse mode versus focus mode. In browse mode NVDA takes over the arrow keys so the user can read through the document; in focus mode keystrokes go to the application. NVDA switches automatically based on what has focus, and a widget with the wrong role makes it switch at the wrong time. A custom listbox that leaves the reader in browse mode means arrow keys scroll the document instead of moving through options, and the user never discovers the control works.

JAWS

Commercial, from Freedom Scientific, and still heavily used in enterprise, government and education where it is centrally licensed and configured. WebAIM's screen reader user survey has consistently shown JAWS and NVDA as the top two on the desktop, with VoiceOver third, so if your buyers are institutions, JAWS is not optional.

Its distinguishing trait is that it tries harder to be helpful. JAWS applies more inference, and will sometimes construct a name for a control from surrounding text where NVDA reports nothing. That sounds like a feature and is a testing hazard: it can mask a missing label completely, so a product that passes a JAWS-only review can fail badly for a NVDA user. It also announces things the others do not, such as clickable on elements carrying handlers, which produces a distinctive kind of noise on a div-heavy interface.

VoiceOver

Built into macOS and iOS, and the iOS one is the one that matters most for consumer products. It is a different interaction model, not just a different voice: the rotor replaces the element lists that NVDA and JAWS use, and on iOS there is no keyboard at all, so every interaction is a gesture. Swipe right to move to the next element, double tap to activate, two-finger swipe up to read from the top.

Test it on a real device. The simulator does not run VoiceOver the way the hardware does, and the bugs you are hunting are timing and focus bugs. The classic one: your single page app changes view, the visual content updates, and VoiceOver focus stays on an element that no longer exists, so the user swipes into nothing. The fix is to move focus deliberately to the new view heading, and it has to be done per route.

On macOS, pair VoiceOver with Safari. It works elsewhere, but Safari is the combination Apple builds for and the one your Mac users are on.

How we run the passes without testing every combination

The combinatorics get silly quickly, so we test the pairings people actually use: NVDA with Firefox and with Chrome on Windows, JAWS with Chrome where your audience justifies it, VoiceOver with Safari on macOS, VoiceOver on a physical iPhone, TalkBack on a physical Android device. That is enough to catch the overwhelming majority of real defects.

Everything gets recorded. A written finding that says the button announces as button, unlabelled invites an argument. A twenty second recording of NVDA saying button, button, button while the auditor tabs across your toolbar ends it. For a distributed engagement across eight or ten timezones, that recording is also the fastest way to transfer the finding, because your developer can watch it at their desk at nine in the morning without anybody being awake in India.

Colour Contrast and the Cases Teams Get Wrong

Contrast is the one criterion everybody has heard of, which is why it is also the one where the same four mistakes turn up in nearly every audit.

The AA numbers first. Body text needs 4.5:1 against its background. Large text gets 3:1, where large means at least 18 point or 14 point bold, roughly 24 pixels or 18.66 pixels bold. Non-text contrast at 1.4.11 requires 3:1 for the parts of a user interface component you need to see to use it, and for graphical objects carrying meaning. AAA raises the text numbers to 7:1 and 4.5:1, which is why almost no brand palette clears it.

Mistake one: testing the default state only

The scanner checks the button as rendered. It does not hover it, focus it, disable it, or put it in an error state. Hover states are the usual culprit because designers lighten a button on hover for a sense of feedback, and the lighter version drops under 4.5:1. Placeholder text is the second, since the grey that looks elegant in a design file is often around 2.5:1 in the browser. Disabled controls are exempt from the contrast requirement, which is a genuine exemption and also a genuine usability problem if the user cannot tell why they are stuck.

Mistake two: ignoring the boundary of the control

Label text passing at 4.5:1 tells you nothing about whether the input can be found. If your text field is white on white with a border at 1.4:1, the border fails 1.4.11, and someone with low vision cannot see where to click. The same problem hits focus rings, toggle switches, checkbox outlines, chart lines and the icon in an icon-only button. Anything you need to perceive to operate the control is in scope.

Mistake three: colour as the only signal

Separate criterion, 1.4.1 Use of Colour, and constantly conflated with contrast. A required field marked only by a red border communicates nothing to a colour blind user even at 12:1 contrast. Same for a status column that is only a coloured dot, a chart that distinguishes six series purely by hue, and a link inside a paragraph that is coloured but not underlined. The fix is a second channel: text, an icon, a pattern, an underline. Not a darker red.

Mistake four: text over images, video and gradients

A hero with white text over a photograph cannot be measured by an automated tool, so it goes unreported, and the failure is real. The photograph changes between breakpoints, and the crop that looked fine on desktop puts your headline over a bright sky on a phone. This is what the standalone Colour Contrast Analyser is for: sample the actual pixels behind the text at each breakpoint, worst case first. The engineering fix is usually a scrim, a solid text panel, or a text shadow with enough spread to carry the ratio on its own.

Dark mode deserves a line of its own. Teams derive dark palettes by inverting, ship them, and never re-run contrast. Pure white text on pure black also causes halation for a lot of readers, so the fix is rarely more contrast. It is a slightly off-black surface and a slightly off-white text colour, checked properly rather than assumed.

Forms, Errors and the Part That Costs You Orders

If you only had budget for one screen, we would spend it on your longest form. Forms are where accessibility failures convert directly into abandoned revenue, because the user has already decided to buy and the interface is the only thing stopping them.

The label rules are simple and broken constantly. Every control needs a programmatic label, which means a label element with a for attribute matching the input id, or an aria-label, or aria-labelledby pointing at visible text. Placeholder text is not a label. It disappears when typing starts, several screen readers ignore it, and it fails at low vision because placeholder grey is usually too light. Wrapping the input inside the label works too and avoids the id mismatch problem entirely, which is why we prefer it in component libraries.

Grouping is the part that gets skipped. Radio buttons and related checkbox sets need a fieldset with a legend, otherwise the reader announces yes and no with no idea what question they answer. Address blocks, date fields split into three inputs, and payment sections all need the same treatment. Then there is Label in Name at 2.5.3: if the visible text says Submit Order and the aria-label says Continue, a voice control user saying click submit order gets nothing, because the accessible name does not contain the visible text. Overriding a visible label with a different aria-label is a common and quietly destructive habit.

Error handling, which is where most forms actually fail

Watch what happens when validation fails on a real submission. In most products the errors appear, the page does not move, and focus stays on the submit button. A sighted user sees red. A screen reader user hears nothing at all and has no idea the submission failed.

The pattern that works: render an error summary at the top of the form, give it tabindex minus one, move focus to it on failed submit, and make each entry a link to the field it refers to. Each field then gets aria-describedby pointing at its own inline message, so the error is read again when the user arrives at the input. Set aria-invalid on the failing controls. Keep the message specific, because 3.3.3 Error Suggestion asks for a correction where one is known: enter your date of birth as DD/MM/YYYY beats invalid input by a distance.

For anything that validates as you type or updates without a page change, the announcement has to go through a live region. 4.1.3 Status Messages covers this: the message must reach assistive technology without stealing focus. Use role status or aria-live polite for confirmations and aria-live assertive only for genuine interruptions. Two implementation details cause most live region bugs. The container must exist in the DOM before the text is inserted, because rendering the whole region at once often announces nothing. And a polite region will queue behind whatever is currently being read, so a message that clears after two seconds may never be heard.

One more, from WCAG 2.2. Redundant Entry means a multi-step form should not ask for the same information twice within one process, and Accessible Authentication means the login cannot depend on solving a puzzle or recalling a code with no alternative available. Both are Level A or AA, both are product decisions, and both tend to land on the roadmap rather than in a sprint.

ARIA, Accessible Names, and Why No ARIA Beats Bad ARIA

The first rule of ARIA, written into the specification's own authoring practices, is not to use ARIA. If a native HTML element does the job, use it, because it arrives with keyboard behaviour, focus handling and platform semantics you would otherwise have to build and maintain yourself.

This is not purism. WebAIM's Million analysis has repeatedly found that home pages using ARIA average more detected errors than pages using none, and the reason is not that ARIA is harmful. It is that ARIA is applied to complicated interfaces by people copying an attribute from a search result without implementing the behaviour it promises.

Because that is the trap. ARIA changes only what is announced. It changes nothing about what the element does. Put role equals button on a div and a screen reader will call it a button, and it still will not respond to Space, still will not be in the tab order, still will not fire on Enter. You have promised the user a button and delivered a decoration. A div with no role at all is at least honestly broken, and the user knows to look elsewhere.

Accessible names, computed rather than declared

The accessible name is what assistive technology announces for a control, and it is computed by a defined algorithm with a priority order that surprises people. aria-labelledby wins. Then aria-label. Then the native source, which is the label element for a form control, the alt attribute for an image, or the element's own text content for a button. Then title, which is a last resort and unreliable on touch.

The practical consequence: an aria-label silently overrides visible text. An icon button containing a visually hidden span reading Delete, given an aria-label of Remove item, announces Remove item. Voice control users then cannot activate it by saying its visible name. When a control has visible text, let that text be the name. Reach for aria-label only where there is no visible text at all, which realistically means icon-only buttons and a handful of landmarks.

Check the result rather than the intention. Open the accessibility tree in DevTools, select the node, read the computed name and role. That takes five seconds and settles the question definitively, which is faster than reasoning about the algorithm.

The patterns that go wrong most often

Custom selects and comboboxes, by a distance. The ARIA Authoring Practices Guide combobox pattern needs a managed focus model, aria-expanded, aria-controls, aria-activedescendant, and full arrow key, Home, End, Escape and type-ahead handling. Most implementations do about a third of that. A native select element, styled as far as CSS allows, is very often the better engineering decision, and the honest recommendation on a lot of audits.

Modals are second. The dialog needs role dialog with aria-modal true, focus moved into it on open, focus trapped inside it while it is open, Escape to close, and focus returned to the trigger afterwards. Missing the return step is the most common half-fix, and it drops the user at the top of the document. The native dialog element with showModal now handles most of this in browsers, and is worth adopting rather than reimplementing.

Then tabs, accordions, tooltips, menus and toasts. The shared failure is the same: the ARIA attributes were copied, the keyboard behaviour was not built. Two rules keep this manageable. Any element with a role that implies interaction must be focusable and must respond to the keys its role implies. And no ARIA at all beats ARIA that lies, every time.

Motion, Animation and prefers-reduced-motion

Motion sensitivity gets treated as a taste preference. It is not. For people with vestibular disorders, large parallax movement, aggressive zoom transitions and scroll-jacked page reveals can cause nausea and dizziness that lasts well beyond the session. The user cannot avoid it by not clicking, because the trigger is scrolling.

The operating system already tells you. macOS, iOS, Windows and Android all expose a reduce motion setting, and it reaches CSS as the prefers-reduced-motion media query and JavaScript through matchMedia. So the test is quick: turn the OS setting on, reload, and see whether anything changed. On most marketing sites nothing does.

Honouring it does not mean stripping every transition. A 150 millisecond fade is not what causes symptoms. What causes symptoms is movement across a large area of the viewport: parallax layers moving at different rates, full-screen slide transitions, elements flying in from off-screen, scroll-driven zoom. Replace those with a fade or with nothing, and leave short state transitions alone, because they carry information about what just happened.

Two related criteria are Level A and often missed. Pause, Stop, Hide at 2.2.2 covers anything that moves, scrolls or auto-updates for more than five seconds, which means your auto-advancing hero carousel needs a real pause control, and a control that appears only on hover does not count. Three Flashes at 2.3.1 covers content flashing more than three times a second, which sounds exotic until somebody embeds a video with a strobe cut in the first two seconds.

One implementation note that saves rework. Set the reduced-motion media query as a global rule in your base stylesheet that cuts animation duration to near zero, then override deliberately for the transitions you want to keep. Doing it per component means the next component ships without it.

Testing With People Who Use Assistive Technology Daily

An auditor with three years of NVDA practice is not a screen reader user. We are careful about that distinction, because the two find different things and only one of them tells you whether your product is usable.

An expert audit finds standards failures. It answers whether the markup, the semantics and the interaction meet the criteria, and it produces the register you remediate against. What it cannot produce is speed, expectation and habit. A daily screen reader user runs at a speech rate most sighted testers find unintelligible, navigates by pulling up a list of headings or landmarks rather than tabbing through everything, and has strong expectations formed by every other site they use. They abandon a flow at the point of confusion rather than working it out, because they have somewhere else to be.

Findings from those sessions are qualitatively different. Not this control lacks an accessible name, but I could not tell whether the order had gone through, so I submitted it again. Not heading levels skip from h2 to h4, but there are forty links before the content and I gave up. That second class of finding never appears in an audit register, and it is the one that changes conversion.

How we run them: task-based rather than exploratory, on the participant's own device with their own settings and their own speech rate, because a stranger's configuration invalidates half the session. Recorded with screen and audio where the participant consents. Participants are paid for their time. And the sessions come after the standards audit, not before, since spending an hour of someone's time discovering an unlabelled button that axe would have caught for free is a waste of their day and yours.

Recruitment is the honest constraint. Finding participants who use JAWS in a specific professional context, or who use switch access, or who use voice control, takes longer than most sprint plans allow, and it usually runs through disability organisations and specialist panels. Plan it weeks ahead. If your timeline will not allow it this release, say so and schedule it for the next one rather than substituting an internal volunteer wearing a blindfold, which produces confident conclusions that are wrong.

How Do You Decide What to Fix First?

An audit of a mature product routinely returns several hundred findings. Handing that over unsorted is how the whole thing stalls, because the team opens the spreadsheet, sees three hundred rows, and closes it. Priority is part of the deliverable, not an afterthought.

First: what makes a task impossible

Anything that blocks completion outright goes to the top regardless of how many pages it affects. A keyboard trap in checkout. A submit button with no accessible name. A payment field that cannot be reached. A route change that strands focus so the user cannot find the confirmation. One blocker on a revenue path outranks two hundred contrast failures in a footer, every time.

Second: multiply by traffic and by journey

A defect on the signup form and the same defect on the press archive are not the same defect. We weight by the number of people who hit the screen and by whether the journey is one you are paid for. This is where analytics earns its keep in an accessibility programme, which surprises people.

Third: fix once, not two hundred times

Sort findings by component rather than by page and the shape of the work changes completely. One icon button in your design system with no accessible name may generate four hundred instances across the site, and it is one pull request. We routinely find that a third of the register collapses into fewer than ten component fixes. Those go first, because they change the ratio between effort and outcome more than anything else on the list.

Fourth: the cheap systemic wins

A handful of fixes take an hour each and remove whole categories of complaint. A lang attribute on the html element, so the speech synthesiser uses the right pronunciation rules. Unique, descriptive page titles. A skip link that genuinely moves focus. A visible :focus-visible style defined once in the base stylesheet. Correct landmark elements in the layout template. None of them is interesting. All of them are worth doing in week one.

Fifth: where the exposure is

Some surfaces attract complaints and legal attention more than others because they are the ones people cannot get around: account creation, login, payment, and anything that is the only route to a service. Whether and how that translates into risk in your jurisdiction is a question for your counsel. We can tell you which screens are failing and how badly. We cannot tell you what that means legally, and you should be suspicious of any vendor who offers to.

What we do with the rest

Everything left over gets scheduled rather than forgotten: batched into the sprints where somebody is already touching that code, or written into the definition of done so the next person to edit the component fixes it on the way past. A register with three hundred open items and no owner is not a plan. Fifty tickets in a backlog with a component name on each is.

Where the Legal Obligations Sit, and Where Our Advice Stops

Read this section as orientation, not as advice. We are engineers. What follows is the map of which frameworks people ask us about and what they generally reference technically, so you can ask your lawyer a sharper question. Nothing here is a legal opinion, and none of it is a statement about your obligations.

United States

The Americans with Disabilities Act does not itself contain a technical web standard. Its application to websites and applications has been worked out largely through enforcement and litigation, and the position varies. Separately, the Department of Justice has issued rulemaking under Title II that points at WCAG 2.1 Level AA for state and local government entities, with compliance timing that depends on the size of the entity. If you sell to public sector bodies in the US, or you are one, that rule and its deadlines are the first thing to put in front of counsel.

Section 508 of the Rehabilitation Act covers federal agencies and, in practice, their suppliers. The revised standards incorporate WCAG Level AA by reference, and federal procurement commonly asks vendors for an accessibility conformance report using the VPAT template published by ITI. We can produce the technical evidence that sits behind such a report. The statement itself is yours, and it should be reviewed by someone qualified before you sign it, because supports, partially supports and does not support are terms with consequences.

Europe

EN 301 549 is the European standard for accessibility requirements in ICT procurement, and it takes its web requirements from WCAG at Level AA. It is what public sector procurement across the EU generally references, and it covers more than web content, including documents, hardware and support services.

The European Accessibility Act is a directive, which means the thing that binds you is the national law each member state passed to implement it. Those implementations are not identical, the scope covers specific categories of products and services rather than everything, and there are exemptions whose thresholds differ. If you sell into the EU, the questions worth asking counsel are which national implementations apply to you, whether your product falls in scope, and what evidence you would need to produce.

Elsewhere

The UK, Canada, Australia and several other jurisdictions have their own instruments, most of which reference WCAG Level AA in some form for at least the public sector. Provincial and state law can add requirements on top of national law. We do not track these well enough to advise on them and would not do so if we did.

The practical takeaway

Whatever the instrument, the technical target lands on WCAG Level AA nearly every time. Which means the engineering work is the same regardless of which acronym is driving the conversation, and you can start it before the legal question is settled. Start with the evidence. Take the evidence to your lawyer. Not the other way round.

Four Situations We Get Called Into

These are composite patterns rather than named clients, and they repeat often enough to be worth writing down.

The design system that scored 100

A B2B analytics product rebuilds its front end on React with a fresh component library. Lighthouse reports 100 on the main dashboard. A customer whose procurement team runs its own check reports that the date range filter cannot be used at all without a mouse.

The filter is a custom combobox: a div with a click handler, a styled list rendered on click, options as list items with click handlers. Every accessible name is present, because somebody added aria-label to each option, so axe reports nothing. There is no keyboard model at all. Arrow keys scroll the page, Escape does nothing, and focus never enters the list. The fix is either the full APG combobox pattern with aria-activedescendant and complete key handling, or a native select where the design allows. We usually recommend the native element for filters and reserve the custom pattern for the search field where type-ahead genuinely matters. Then a Playwright test that drives the component by keyboard only, so it cannot regress quietly.

The checkout that fails silently

A direct-to-consumer retailer sees a small but persistent cluster of abandoned orders at the payment step and cannot explain it. The form validates on submit. Errors render inline in red with a red border. Focus stays on the pay button. There is no summary and no live region.

For a screen reader user the submission just does nothing, twice, and then they leave. For a colour blind user the red border alone carries the entire message. Three failures stack: 1.4.1 on colour as the only indicator, 3.3.1 on error identification, and 4.1.3 because nothing is announced. The fix is a focused error summary with links to each field, aria-describedby on each control pointing at its message, aria-invalid set on the failures, text alongside the colour, and a specific correction where the format is known. It is a couple of days of work on the one screen that pays for the audit.

The RFP with three weeks on the clock

A SaaS vendor is bidding for a public sector contract and the tender asks for an accessibility conformance report against EN 301 549. Nobody internally has ever produced one, and the deadline is short.

The work here is triage and honesty rather than remediation. We scope to the product surfaces the tender covers, run the audit, and produce evidence per criterion including the failures. The temptation is to claim full support and hope nobody checks. Public sector evaluators do check, and an overclaim discovered later is a worse position than a partial one declared upfront with a dated remediation plan attached. What we deliver is the technical evidence and the criterion-by-criterion findings. The conformance statement is signed by you, with your counsel.

The marketing rebuild that made people ill

A brand site relaunches with a scroll-driven build: full viewport parallax sections, a hero that zooms on scroll, cards flying in from the sides. The design work is genuinely good. Support then receives complaints from people who could not read the pricing page without feeling sick, and the reduce motion setting on the operating system changes nothing.

Alongside it, the animation library uses CSS transforms to reorder the visual layout, so the tab order runs bottom to top through one section. And the hero carousel auto-advances every four seconds with no pause control, which is 2.2.2 at Level A. The fix costs less than anyone expects: a prefers-reduced-motion block that reduces the large movements to fades, DOM order corrected to match the visual order, a real pause button on the carousel. The design survives. It just stops being mandatory.

How We Run Accessibility Testing From India Across Your Timezone

Being direct about the clock, because vague answers here waste everybody's first month. A standard working day in India runs 09:30 to 18:30 IST. Against London that leaves roughly four hours of live overlap in the afternoon. Against New York there is essentially no live overlap: our day is ending right around when yours begins. Against San Francisco, essentially none. Against Sydney you get most of your afternoon; against Auckland, very little without a shift.

Anybody who tells you that gap disappears for free is selling you something. It closes by paying for a shifted rota, which is a real cost in coordination and in people's evenings, or it closes by designing the work so it does not need both sides awake. The overlap window and any shift pattern get agreed with you before work starts rather than assumed.

Why accessibility work suits this better than most

An audit is asynchronous by nature. The testing produces artefacts, and the artefacts travel. The unit of handover is not a status meeting, it is a finding: the criterion, the reproduction steps, the pairing used, the recording with the screen reader audio, the suggested code fix. A developer in Toronto opens it cold at nine in the morning and has everything needed to start. No question of what did you mean by focus is lost.

The recordings do more work than any other artefact. Accessibility findings are argued about far more than functional bugs, usually because the person reading the ticket has never heard a screen reader. Forty seconds of NVDA announcing button, blank, blank while somebody tabs across your toolbar ends that conversation permanently, and it costs nothing to watch at whatever hour suits.

The cadence we default to

A written standup posted before the India day ends, which lands in your morning: what was tested, what was found, what is blocked. A live session in the overlap window at whatever frequency the phase needs, weekly during audit, more often during remediation. Findings filed continuously into your tracker rather than dropped as one report at the end, because a register that arrives complete on day twenty is a register nobody starts until day twenty-one. A demo at the end of each phase, recorded, so the people who could not make the hour still see it.

Talent and why this skill exists in India

Accessibility engineering grew in India largely on the back of enterprise and government work, where Section 508 and EN 301 549 requirements have been flowing down through supplier contracts for years. That has produced people who have written conformance evidence, argued a finding with an evaluator, and remediated somebody else's design system rather than only their own. It is a smaller pool than general QA. Screening for it means asking a candidate to audit a live page in front of you with a screen reader running, which sorts the field in about fifteen minutes.

Code, access and IP

The team works inside your repository, your tracker and your review process, on accounts your administrators provision and revoke. Ownership of everything produced, the confidentiality terms and the data handling arrangements are settled in the agreement before work starts, and they are yours to set. Where testing needs production-like data, we would rather work from anonymised fixtures than from a copy of your live database, which is usually simpler for both sides.

What Goes Wrong, and How We Handle It

Every engagement hits at least one of these. Better to name them now.

The audit lands and nothing gets fixed

The most common failure, and it is structural rather than technical. A report goes to a manager, the manager forwards it, nobody owns a line of it, and it ages. We mitigate by filing findings directly into your tracker as they are found, grouped by component with a named owner, and by keeping the register small through deduplication. If a report is going to sit unread, we would rather find that out in week one.

Third-party components you cannot change

The payment iframe, the chat widget, the embedded video player, the analytics consent banner. These fail audits constantly and sit outside your repository. What we do is document the failure against the criterion, record it in the register as vendor-owned, and give you the specific technical wording to send to that vendor, because generic complaints go nowhere and a criterion reference with a reproduction gets escalated. Where the vendor will not move, the remaining options are an accessible alternative route to the same outcome, or replacing the vendor, and that is a commercial decision rather than an engineering one.

The design cannot pass as drawn

Sometimes the brand palette does not reach 4.5:1 and the answer is a different colour. Sometimes the interaction only works by dragging. These findings go to design, not to engineering, and they take longer because they touch identity. Raising them early, with the specific ratio and the specific criterion, gets a far better reception than raising them the week before launch. Working with a designer who has been through this before helps, which is part of why our UI and UX design and testing work often run together rather than in sequence.

Everything regresses in two releases

Guaranteed without a gate. A one-off audit with no CI coverage, no component-level tests and no change to the definition of done leaves you buying the same audit again next year. The automation is the cheap part of the engagement and it is the part that decides whether the expensive part holds.

Scope creep from real bugs

An accessibility audit surfaces plenty of things that are not accessibility problems: broken links, a component that crashes on empty state, a race condition on slow connections. We log them separately and hand them over rather than fixing them silently, because a change nobody asked for is the fastest way to lose trust in the register.

Someone has already installed an overlay

It happens, usually after a scare and a sales call. We will say plainly that it does not fix the underlying markup, and that testing has to be done with it disabled to see the real product. Removing it is your call. Just do not count it as remediation.

Engagement Models

Three shapes, and most clients move between them rather than picking one forever.

A scoped audit

Fixed set of templates and journeys, fixed set of criteria, a delivered register with evidence and a priority order, and a re-test pass after you have remediated. This is the right starting point when you have a deadline, a tender, or a complaint, and you need to know where you stand. It ends with a document rather than with code.

Audit plus remediation

The same audit, then our engineers fix the components inside your repository, working to your review process. Suits teams who agree with the findings and do not have the bandwidth or the specific expertise to act on them. The component library work is usually the bulk of it, and it is the part with the best return.

A dedicated engineer or a small embedded team

Accessibility specialists working continuously inside your team: reviewing designs before build, reviewing pull requests, maintaining the automated gates, running the manual passes each release, and building the practice so your own engineers stop needing the review. This is what teams choose once accessibility has become a standing requirement rather than a project. If your need is broader than testing, the same people are available as dedicated React developers in India and across the other stacks we work in.

Commercial terms, notice, handover and ownership are set in the agreement before work starts. We do not publish those on a web page, because the honest version depends on what you actually need.

Where This Sits Alongside Our Other Work

Accessibility work rarely arrives on its own. When the finding is that your component library is the root cause, the fix is front end engineering rather than testing, and it runs through our front end development team. Where the failures start in the design rather than the code, contrast, focus treatment and interaction patterns get resolved with UI and UX design before anybody writes a line of CSS.

If the wider question is that your test coverage does not support the confidence you are projecting, start with QA and testing and fold accessibility into it as one more gate rather than a separate programme. For native iOS and Android, VoiceOver and TalkBack testing sits with the same people who build the apps, so it is scoped inside mobile app development rather than bolted on afterwards.

And where the honest answer is that you need the capability in-house rather than a vendor engagement, hiring dedicated React developers in India who already work this way is a different commercial shape for the same skills.

Frequently Asked Questions About Accessibility Testing in India

Can you make our product WCAG 2.2 AA compliant?

We can audit against the criteria, evidence every finding, fix what you ask us to fix and re-test. What nobody honestly sells you is compliance as an outcome, because conformance is a claim you make about one version of one product at one date, and it stops being true the next time somebody ships a component. Whether that claim carries legal weight where you operate is a question for your counsel, not for a testing vendor.

Is running axe-core in CI enough on its own?

No, and the tool authors say so too. Deque, who build axe-core, put their own automated coverage at roughly 57 percent of issues, and that figure covers the things a rules engine can decide from the DOM. It cannot judge whether your alt text describes the image, whether the reading order makes sense, whether a custom widget responds to arrow keys, or whether a screen reader user can finish checkout. Keep axe in CI for regressions. Do not read a green build as a pass.

We already test with NVDA. Do we still need JAWS?

For a consumer web product, NVDA plus VoiceOver on iOS covers most of what you will hit. JAWS matters when your users are in enterprise, government or education, where it is often the screen reader the employer has licensed and configured. The two disagree in real ways: JAWS applies more heuristics and will sometimes announce a name for a control that NVDA reports as unlabelled, which means a JAWS-only pass can hide a genuine bug.

What is your position on accessibility overlay widgets?

We do not install them and we will tell you plainly if you have one. An overlay script cannot know what your image is of, cannot decide the correct heading order and cannot rewrite a custom widget into something keyboard operable. It sits on top of the markup that is causing the problem. The Overlay Fact Sheet collects the practitioner position on this and is signed by a large part of the accessibility field, including people who use screen readers daily.

How do you scope an audit when we have hundreds of pages?

By counting unique templates and critical journeys instead of URLs. Two thousand product pages built from one template are one template, and one fix to that template is two thousand pages fixed. So we inventory the distinct layouts, the shared components in your design system, and the three or four journeys where failure actually costs you something, then test those exhaustively and sample the rest.

Our app is a dense data grid with drag and drop. Is that even testable?

Yes, and it is the work worth paying for, because that is exactly where a scanner reports nothing useful. Grids need a managed focus model, correct row and column semantics, and keyboard equivalents for every pointer action. WCAG 2.2 added a criterion on dragging movements for precisely this case. Expect the findings to be about interaction design rather than markup, and expect some of them to change the component API.

Do you test native mobile apps as well as web?

Yes. iOS gets VoiceOver on a real device with the rotor and Switch Control, Android gets TalkBack, and both get a pass on Dynamic Type or font scaling at the largest setting, which is where fixed height containers usually break. The platform guidelines differ from WCAG in wording, so we report against both: the WCAG criterion for your paper trail and the platform API that actually needs changing.

How does an accessibility team in India fit our release cycle?

A 09:30 to 18:30 IST day gives a London team about four hours of live overlap and a New York team almost none, since our day ends right around when yours begins. So we build the engagement around artefacts rather than meetings: every finding ships with a short screen recording carrying the screen reader audio, the exact keys pressed, and the code level fix. The overlap window and any shift pattern get agreed with you before work starts.

Send Us One Screen and We Will Tell You What Breaks

Pick the form or the flow you are least confident about. We will run a keyboard pass and a screen reader pass on it, and come back with what a real user hits, which criteria it fails, and what the fix looks like in your code.

Start the Conversation