freeCodeCamp: Spacing breaking test: Learn HTML by Building a Cat Photo App - Step 12

Describe the Issue

A camper managed to fail the challenge despite having a close enough correct solution for the challenge. It even displays correctly in the browser.

Affected Page

https://www.freecodecamp.org/learn/2022/responsive-web-design/learn-html-by-building-a-cat-photo-app/step-13

Your code

<p>See more <a href="https://freecatphotoapp.com">  cat photos </a> in our gallery.</p

Expected behavior

I do not believe the tests should be failing if there are spaces around the words “cat photos” in the anchor element. The user should be proceeding to another challenge.

Screenshots

No response

System

  • Device: Desktop
  • OS: Windows 10
  • Browser: FireFox
  • Version: 118.0.2

Additional context

No response

About this issue

  • Original URL
  • State: closed
  • Created 9 months ago
  • Reactions: 2
  • Comments: 28 (24 by maintainers)

Most upvoted comments

They shouldn’t be messing with that p element in the first place in step 13. I think step 12 is more relevant for this issue.

And yes, a lot of people add extra spaces in the link text and get bit by this. This was mentioned in issue #49023 and I think the consensus is that a test should be added specifically to check for the extra white space.

I would normally agree that extra white space should not be an issue and the tests should not be so strict about it. But for link text I can see the reasoning. If you add extra white space after “photos” then you will see the underline on the link extend past the word “photos” into the white space after the word. This is one of those few instances where white space actually does make a difference.

Hey, I am a first-timer and I would like to solve this issue

hey everyone i think that when it comes to whitespaces - the user includes whitespaces before or after or in both sides of the anchor text - if we want to ignore whitespaces i think a regex should just be included in the source code and replaces it with an empty string ‘’" like @Yash-Ambekar showed in a code earlier. So that wouldn’t be a big issue later on.

And about typos normally they shouldn’t be allowed. Like if the user is supposed to type ‘cat photos’ and instead they type ‘cat photo’ that obviously shouldn’t pass and they shouldn’t be able to go to the next challenge until they enter the exact anchor text asked. Hope this was understandable.

@jeremylt should I raise a PR then? or is this issue not open for PRs?

@jeremylt Is this the correct way now?

The link’s text should be cat photos. You have either omitted the text or have a typo.

// checks for typo
const nestedAnchor = $('p > a')[0];
const innerText = nestedAnchor.innerText.toLowerCase();
assert(
	/^\s*cat photos\s*$/.test(innerText)
);

NEXT TEST

The link’s text should be cat photos. You either have leading or ending whitespaces.

//checks for whitespaces
const nestedAnchor = $('p > a')[0];
const innerText = nestedAnchor.innerText.toLowerCase();
assert(
	innerText === 'cat photos'
);

@jeremylt

I have three options of writing the test:

  1. Simply telling the users to avoid whitespaces when the typo test fails and this text is prompted to the user ‘The link’s text should be cat photos. You have either omitted the text or have a typo or have extra whitespaces.’ and not adding a new test.

  2. Write separate tests for checking typos and whitespaces.

The link’s text should be cat photos. You have either omitted the text or have a typo.

const nestedAnchor = $('p > a')[0];
assert(
  nestedAnchor.innerText.toLowerCase().replace(/\s+/g, ' ') === 'cat photos'
);

AND The link text seems to contain extra whitespaces.

const pText = document.querySelector('p').innerText.toLowerCase(); //get the inner text which includes text inside anchor tag
const whiteSpacesCheck = /^(\S+\s\S+)+$/.test(pText);
assert(
  whiteSpacesCheck 
); 
  1. Combine both the tests into one single test. The link’s text should be cat photos. You have either omitted the text or have a typo or have extra whitespaces.
const nestedAnchor = $('p > a')[0];
const pText = document.querySelector('p').innerText.toLowerCase(); //get the inner text which includes text inside anchor tag
const typoCheck = nestedAnchor.innerText.toLowerCase().replace(/\s+/g, ' ') === 'cat photos'; //checking for typos
const whiteSpacesCheck = /^(\S+\s\S+)+$/.test(pText);
assert(
  typoCheck || whiteSpacesCheck 
); //if either is false then it will fail 

Please tell me which option solves the issue. If none of them are correct then please elaborate more on the proper solution I am unable to understand the proposed solution. Also sorry if this is causing you inconvenience.

I think here we should actually expect correct whitespace.

Nope. I think we should check whitespace and typos separately.

@jeremylt does this work then?


The link’s text should be cat photos. You have either added whitespaces before or after the text

const nestedAnchor = $('p > a')[0];
const hasWhiteSpaceBeforeCat = /^\s+/.test(nestedAnchor );
const hasWhiteSpaceAfterPhotos = /\s+$/.test(nestedAnchor );
assert(
  hasWhiteSpaceBeforeCat || hasWhiteSpaceAfterPhotos
);

I think here we should actually expect correct whitespace.

Nope. I think we should check whitespace and typos separately.

@jeremylt Sorry if I am wrong about this but do you mean we should make the test less strict and allow whitespaces?

I think it would probably be better to mention whitespace separately since it’s early in the curriculum

@jeremylt There is a test where the user is prompted for typos. So instead of writing a test for just detecting whitespaces can’t we just mention to avoid whitespaces in that prompt?

image

Please read our contributing guide. This issue is not marked as ready for contributions and we do not assign issues.

I think here we should actually expect correct whitespace.

oh ok i get it

I think we agreed above that we don’t want to ignore the whitespaces

I will repeat what I posted in the PR here as well.


If we are really concerned about the anchor element content we shouldn’t be lowercasing it or removing anything and we should use textContent or innerHTML and not innerText.

Something about this I didn’t realize is the spacing inside innerText only happens if the a element is followed by outside text (which seems bizarre).

<p id="test1">testing <a href=""> cat photos </a> test</p>
<p id="test2">testing <a href=""> cat photos </a></p>
const nestedAnchor1 = document.querySelector('#test1 > a');
const nestedAnchor2 = document.querySelector('#test2 > a');

console.log('test 1', nestedAnchor1.innerText.toLowerCase().replace(/\s+/g, ' ') === 'cat photos') // false
console.log('test 2', nestedAnchor2.innerText.toLowerCase().replace(/\s+/g, ' ') === 'cat photos') // true

textContent and innerHTML will always show the actual element content.

console.log('test 1', nestedAnchor1.textContent.toLowerCase().replace(/\s+/g, ' ') === 'cat photos') // false
console.log('test 2', nestedAnchor2.textContent.toLowerCase().replace(/\s+/g, ' ') === 'cat photos') // false

We should replace jQuery for any test we see that is using it.

The second test doesn’t need to be that complicated. It should match for the string literal without extra spaces.

yeah sorry I was too engrossed in learning regex xD You can check the second test I have updated it.

I’m saying that test needs to be two tests.

The test for the p element content probably also needs an adjustment to be agnostic to whitespace? And then this test for whitespace would follow?

I’m talking about modifying the current test that checks for_both_ typos and spaces at the same time.

This is the current test for only typos.


The link’s text should be cat photos. You have either omitted the text or have a typo.

const nestedAnchor = $('p > a')[0];
assert(
  nestedAnchor.innerText.toLowerCase().replace(/\s+/g, ' ') === 'cat photos'
);

As far as I can understand you want this modification to the test right?

const nestedAnchor = $('p > a')[0];
const pText = document.querySelector('p').innerText.toLowerCase(); //get the inner text which includes text inside anchor tag
const typoCheck = nestedAnchor.innerText.toLowerCase().replace(/\s+/g, ' ') === 'cat photos'; //checking for typos
const whiteSpacesCheck = /^(\S+\s\S+)+$/.test(pText);
assert(
  typoCheck || whiteSpacesCheck 
); //if either is false then it will fail 

The test for the p element content probably also needs an adjustment to be agnostic to whitespace? And then this test for whitespace would follow?

I’m talking about modifying the current test that checks forboth typos and spaces at the same time.

@jeremylt This regex pattern /^(\S+\s\S+)+$/ tests true for sentences with single whitespace between words and no whitespaces before and after the starting and ending word respectively. You can try below code for verifying that

function testWhiteSpaces(inputString) {

  const pattern = /^(\S+\s\S+)+$/;

  const result = pattern.test(inputString);

  return result;
}

console.log(testWhiteSpaces(' Extra white spaces '))
console.log(testWhiteSpaces('Extra  white  spaces'))
console.log(testWhiteSpaces('Extra white spaces'))

So I can write a single test to verify if there are no extra whitespaces between words and no whitespaces before and after the first and last word. So if I get the innerText of the p tag then I can just run the test on that to verify the text inside the nestedAnchor tag.

The test for the p element content probably also needs an adjustment to be agnostic to whitespace? And then this test for whitespace would follow?