Repository: dequelabs/axe-core (JavaScript)

Issue:
axe core throws relying on color alone false positive issue when the link and surrounded text have same color
### Product

axe-core

### Product Version

4.5.1 and 4.5.2

### Latest Version

- [X] I have tested the issue with the latest version of the product

### Issue Description

#### Expectation
If the link text and the surrounded text color are same, then this check should not take place as there is no color alone usage here.

#### Actual
Axe-core flags an issue here assuming there is color alone since there is no additional indicators for the link surrounded with text.

#### How to Reproduce
1. Launch the URL - https://online.citi.com/US/ag/investing/investingwithciti
2. Select continue button on the modal.
3. Now run the axe-core using axe Expert and axe DevTools
4. Notice false positive raised for one of the links in the footer section where the link and surrounding text colors are same.

#### Screenshot
<img width="1718" alt="False Positive_color alone" src="https://user-images.githubusercontent.com/71381558/211107353-05efbf91-be97-4c1f-aca6-dc6ba1e5fa77.png">



Discussion: This is not a false positive, if you look at the "fix this" section you will see that it is complaining that the text contrast with the surrounding text is too low - which is 100% accurate.

@WilcoFiers should we change the help text to make it more precise?
@dylanb Contrast is low here because the link and surrounding text has same color. The check supposed to be done only when we have a link text distinguished by different color (color alone with no additional indicators) with surrounding text, hence this is not a valid test here. We are not checking basic text contrast here. This is more of a usability issue and not A11y. 

@melaniephilipp
@dylanb You can't fail it under 1.4.1 Use of Color when link text and surrounding body text are the same color because there is literally no use of color to differentiate the link text from the body text. 
Some additional context to this issue: https://github.com/w3c/wcag/issues/1467
In the specific example, the link DOES have color to distinguish it from the background UNTIL you hover it and then it does not - so do we fail it under 1.4.11 because the hover state does not pass 3:1 from the surrounding text?
@dylanb I don't see any change in color for the link text even on hover as well. Moreover user has additional indicators (such as hand symbol) to know it is a link and not static text. I believe 1.4.1 Use of Color refers to more of default state/behavior.

<img width="1718" alt="image" src="https://user-images.githubusercontent.com/71381558/211371065-cbd8ca8d-5ed3-4a96-b3d0-c2c9ed022aea.png">

@melaniephilipp Further thoughts?
@dylanb 1.4.11 doesn't compare link text (in any state) to surrounding non-link text. It only requires "a contrast ratio of at least 3:1 against adjacent color(s)...". The adjacent color to the link text is its background - and that is covered by the higher standard of 1.4.3. (We fail the text in links that falls below 4.5:1 with their background in their hovered (or focused) state under 1.4.3.)
looks like a false positive to me then
I agree, axe-core should pass if the colors are identical. Good catch.
@WilcoFiers Thanks for the confirmation. Do you have an estimate of release timing to remove the false positive? Thanks!



Fix (patch):
diff --git a/doc/check-options.md b/doc/check-options.md
index 0f6c60d027..87c6adda42 100644
--- a/doc/check-options.md
+++ b/doc/check-options.md
@@ -36,6 +36,7 @@
   - [region](#region)
   - [inline-style-property](#inline-style-property)
   - [invalid-children](#invalid-children)
+  - [link-in-text-block](#link-in-text-block)
 
 ## How Checks Work
 
@@ -538,3 +539,12 @@ This evaluation method is used in the `list` and `definition-list` rule to deter
 | `validNodeNames` | Nodes without role allowed as children                                              |
 | `validRoles`     | Roles allowed on child elements                                                     |
 | `divGroups`      | Whether the child nodes can be grouped in a div without any role (false by default) |
+
+### link-in-text-block
+
+This evaluation method is used in the `link-in-text-block` rule and tests that either the foreground color or the background color has sufficient contrast between the link text and the surrounding text.
+
+| Option                  | Default | Description                                                                 |
+| ----------------------- | :------ | :-------------------------------------------------------------------------- |
+| `requiredContrastRatio` | `3`     | Minimum contrast needed to pass the check between text or background colors |
+| `allowSameColor`        | `true`  | Whether links with colors identical to its surroundings should pass         |
diff --git a/lib/checks/color/link-in-text-block-evaluate.js b/lib/checks/color/link-in-text-block-evaluate.js
index df9b03f446..acadb1aec5 100644
--- a/lib/checks/color/link-in-text-block-evaluate.js
+++ b/lib/checks/color/link-in-text-block-evaluate.js
@@ -25,7 +25,7 @@ function isBlock(elm) {
 }
 
 function linkInTextBlockEvaluate(node, options) {
-  const { requiredContrastRatio } = options;
+  const { requiredContrastRatio, allowSameColor } = options;
 
   if (isBlock(node)) {
     return false;
@@ -86,6 +86,10 @@ function linkInTextBlockEvaluate(node, options) {
     return undefined;
   }
 
+  if (allowSameColor && textContrast === 1 && backgroundContrast === 1) {
+    return true;
+  }
+
   // Report bgContrast only if the background changes but text color stays the same
   if (textContrast === 1 && backgroundContrast > 1) {
     this.data({
diff --git a/lib/checks/color/link-in-text-block.json b/lib/checks/color/link-in-text-block.json
index 767697de31..04c21841cb 100644
--- a/lib/checks/color/link-in-text-block.json
+++ b/lib/checks/color/link-in-text-block.json
@@ -2,7 +2,8 @@
   "id": "link-in-text-block",
   "evaluate": "link-in-text-block-evaluate",
   "options": {
-    "requiredContrastRatio": 3
+    "requiredContrastRatio": 3,
+    "allowSameColor": true
   },
   "metadata": {
     "impact": "serious",