Want to execute all test cases n times in Cypress

I am a beginner in Cypress. I use Cypress with javascript to perform automation testing.

Question: How can I iterate all it blocks n times?

Description: In a JSON file, one key has an array including names of different profiles. I have one spec file, in which I have multiple it() blocks. Now I want to run my spec file for all profiles available in a key.

For that, I tried below solution:

TestData.JSON

{
"test": {
    "customerAccountName": "RD test R97 01 new",
    "userRole": "Customer Admin",
    "profiles": ["Generic SIP Service", "Genesys PureCloud"],
    "profile": "",
    "serviceCarrier": "",
    "isCarriage": "",
    "type": "",
    "blockSize": ""
}
"stage": {
    "customerAccountName": "RD test R97 01 new",
    "userRole": "Customer Admin",
    "profiles": ["Generic SIP Service", "Genesys PureCloud"],
    "profile": "",
    "serviceCarrier": "",
    "isCarriage": "",
    "type": "",
    "blockSize": ""
}

TestSpec.js

describe("Create, edit, pause, resume and delete Generic SIP Service", function () {

let siteTestData, credentials, SIPServiceTestData, profiles;
before(function () {

cy.fixture('credentials').then(function (testdata) {
  credentials = testdata[window.environment]

  //Login to a portal if require
  if (isLoginRequire(credentials.sausername, credentials.sapassword)) {
    cy.loginAs(credentials.url, credentials.sausername, credentials.sapassword)
  }
})

//Get test data from 'genericSIPServiceTestData' file
cy.fixture('SIPServiceTestData').then((testData) => {
  SIPServiceTestData = testData[window.environment]
  profiles = SIPServiceTestData.profiles
})

//Get test data from 'siteTestData' file
cy.fixture('siteTestData').then(function (testdata) {
  siteTestData = testdata[window.environment]
  //If siteName is empty, add site name
  if (siteTestData.siteName == '') {
    siteTestData.siteName = 'Automation site ' + getUTCTime()
  }
  //If siteEmail is empty, add site email
  if (siteTestData.siteEmail == '') {
    siteTestData.siteEmail = 'automationtestsite' + getUTCTime() + '@gmail.com'
  }
  //If updateSiteName is empty, add site name to update
  if (siteTestData.updateSiteName == '') {
    siteTestData.updateSiteName = 'Update ' + siteTestData.siteName
  }
})
})

it(“Load test profiles”, function () {

Array.from(profiles).forEach($profile => {


  describe('test json loop', function () {

    beforeEach(() => {
      SIPServiceTestData.profile = $profile
    })

    after(() => {
      console.log('inside after')
      // Only log out if require
      if (isLoginRequire(credentials.sausername, credentials.sapassword)) {
        cy.logout();
      }
    });

    it("Navigate to Customer account", function () {
      //Navigate to customer account
      clickCustomer(SIPServiceTestData.customerAccountName)
      //Verify services header on services page
      verifyServicesHeader()
    })

    it("Verify either account is existing or new", function () {
      isAccountNew(siteTestData)
    })

    it("Click on 'Add new service' button, select SIP service and Navigate to 'Select numbers' page", function () {
      //Click on services tab
      clickServicesTab();
      //Add service button should be enable on services page
      getAddServiceButton().should('be.visible').and('be.enabled').and('have.text', 'Add New Service').click();
      //Select profile and carrier, and navigate to select numbers page
      selectProfileAndCarrier(SIPServiceTestData);
      //Verify sub header
      getAccountName().should('be.visible').and('have.text', SIPServiceTestData.customerAccountName)
      //Verify header section and search field on select numbers page
      verifyHeaderOnSelectNumberPage(SIPServiceTestData)
      //Verify tooltip text on hover of inventory number on select number page
      verifyTooltipOnSelectNumberPage()
      //Select number
      selectNumberForServices()
      //Set details of selected number into json
      setSelectedNumberDetails(SIPServiceTestData)
    })
  })
})
});
})

When I run above code it works fine. But Cypress chrome window doesn’t show all it blocks in it’s UI.
enter image description here

Is there any solution for this issue? If not…
Is there any other solution to iterate it block multiple times and it works normally?

Would this Navigation menu pass an accessibility test?

I am trying to improve my skills in developing accessible elements for my WordPress theme since the new European accessibility act will soon come into effect.

I’d like to show the HTML that my custom main menu walker generates and the javascript that goes with it, and it would be great if people could comment on whether this would pass an accessibility check.

Why am I asking this?

Online, you can find a lot of accessibility checkers, guides, and standards on what’s expected from an accessible main menu navigation. Yet, the information either contradicts each other or is a bit open-ended. Thus, I have a hard time understanding if what I am doing is a step in the right direction.

Bellow is the HTML that is generated by my custom walker class.

<nav id="main-menu" class="main-menu" aria-label="Main Navigation">
    <section class="menu-toggle-section">
        <button id="menu-toggle" class="menu-toggle" aria-label="Button for showing or hiding the Main Menu from view.">
            Menu
        </button>
    </section>
    <ul class="main-menu-list">
        <li id="menu-item-2469" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-home current-menu-item page_item page-item-2206 current_page_item menu-item-2469">
            <a href="https://darkfolklore.local/" aria-current="page" role="menuitem">Home</a>
        </li>
        <li id="menu-item-2588" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-2588">
            <a href="https://darkfolklore.local/services/" role="menuitem">Services</a>
        </li>
        <li id="menu-item-2470" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-2470">
            <a href="https://darkfolklore.local/blog/" role="menuitem">Blog</a>
            <button class="dropdown-button" aria-controls="dropdown-0" aria-haspopup="true" aria-expanded="false" aria-label="Toggle button for Blog submenu">
                <span class="dropdown-button-content" aria-hidden="true">+</span>
            </button>
            <ul class="sub-menu" role="menu" id="dropdown-0" aria-hidden="true">
                <li id="menu-item-2613" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-2613">
                    <a href="https://darkfolklore.local/block-image/" role="menuitem">Block: Image</a>
                </li>
                <li id="menu-item-2610" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-has-children menu-item-2610">
                    <a href="https://darkfolklore.local/birds-and-more-birds/" role="menuitem">Birds and More Birds</a>
                    <button class="dropdown-button" aria-controls="dropdown-1" aria-haspopup="true" aria-expanded="false" aria-label="Toggle button for Birds and More Birds submenu">
                        <span class="dropdown-button-content" aria-hidden="true">+</span>
                    </button>
                    <ul class="sub-menu" role="menu" id="dropdown-1" aria-hidden="true">
                        <li id="menu-item-2611" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-has-children menu-item-2611">
                            <a href="https://darkfolklore.local/wp-6-1-font-size-scale/" role="menuitem">WP 6.1 Font size scale</a>
                            <button class="dropdown-button" aria-controls="dropdown-2" aria-haspopup="true" aria-expanded="false" aria-label="Toggle button for WP 6.1 Font size scale submenu">
                                <span class="dropdown-button-content" aria-hidden="true">+</span>
                            </button>
                            <ul class="sub-menu" role="menu" id="dropdown-2" aria-hidden="true">
                                <li id="menu-item-2616" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-2616">
                                    <a href="https://darkfolklore.local/block-gallery/" role="menuitem">Block: Gallery</a>
                                </li>
                            </ul>
                        </li>
                        <li id="menu-item-2614" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-2614">
                            <a href="https://darkfolklore.local/block-button/" role="menuitem">Block: Button</a>
                        </li>
                    </ul>
                </li>
                <li id="menu-item-2615" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-2615">
                    <a href="https://darkfolklore.local/block-cover/" role="menuitem">Block: Cover</a>
                </li>
            </ul>
        </li>
        <li id="menu-item-2471" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-2471">
            <a href="https://darkfolklore.local/contacts/" role="menuitem">Contacts</a>
        </li>
        <li class="menu-item">
            <a role="menuitem" aria-haspopup="false" aria-expanded="false" href="https://darkfolklore.local/wp-login.php?redirect_to=https%3A%2F%2Fdarkfolklore.local%2F">Sign-in</a>
        </li>
        <li class="menu-item">
            <a role="menuitem" aria-haspopup="false" aria-expanded="false" href="https://darkfolklore.local/wp-login.php?action=register">Register</a>
        </li>
    </ul>
</nav>

The javascript for my menu.

document.addEventListener('DOMContentLoaded', function() {

    //* Clicking on menu item button.
    // Get all dropdown buttons
    const dropdownButtons = document.querySelectorAll('.dropdown-button');
    // Add to each button...
    dropdownButtons.forEach(function (button) {
        // If the button iss clicked...
        button.addEventListener('click', function () {
            // Get the dropdown menu.
            const submenu = document.getElementById(button.getAttribute('aria-controls'));
            const openChildren = submenu.getElementsByClassName('sub-menu visible');

            if(openChildren) {
                for (const childMenu of openChildren) {
                    childMenu.classList.remove('visible');
                    childMenu.classList.add('hidden');

                    childMenu.setAttribute('aria-hidden', 'true');
                
                    const childButton = childMenu.previousElementSibling;
                    childButton.setAttribute('aria-expanded', 'false');
                
                    const buttonText = childButton.querySelector('.dropdown-button-content');
                    if (buttonText) {
                        buttonText.textContent = '+';
                    }
                }
            }

            if (submenu.classList.contains('visible')) {
                submenu.classList.remove('visible');
                submenu.classList.add('hidden');

                submenu.setAttribute('aria-hidden', 'true');

                button.setAttribute('aria-expanded', 'false');

                const buttonText = button.querySelector(".dropdown-button-content");
                buttonText.textContent = '+';
            } else {
                submenu.classList.remove('hidden');
                submenu.classList.add('visible');

                submenu.setAttribute('aria-hidden', 'false');

                button.setAttribute('aria-expanded', 'true');

                const buttonText = button.querySelector(".dropdown-button-content");
                buttonText.textContent = '-';
            }
        });
    });

    //* If the menu item looses focus while Tab or Tab + Shift is pressed.
    document.addEventListener('focusout', function (event) {
        const focusedElement = event.target;

        // Check if the focused element is the last menu item in a submenu
        if (focusedElement.getAttribute('role') === 'menuitem') {
            const subMenu = focusedElement.closest('.sub-menu');
            if (subMenu) {
                const button = subMenu.previousElementSibling;
                // Delay the check to allow the next focused element to be determined
                setTimeout(() => {
                    // Check if focus is still inside the submenu
                    if (!subMenu.contains(document.activeElement)) {
                        // Remove the .visible class from the submenu
                        button.focus();
                        button.setAttribute('aria-expanded', 'false');
                        subMenu.classList.add('hidden');
                        subMenu.classList.remove('visible');

                        subMenu.setAttribute('aria-hidden', 'true');

                        const buttonText = button.querySelector('.dropdown-button-content');
                        if (buttonText) {
                            buttonText.textContent = '+';
                        }
                    }
                }, 0);
            }
        }
    });

    //* Enable keyboard buttons.
    document.addEventListener('keydown', function (event) {
        const focusedElement = document.activeElement;

        //* Escape: Close the menu that contains focus and return focus to the element or context, e.g., menu button or parent menuitem, from which the menu was opened.
        if (event.key === 'Escape') { 
            const subMenu = focusedElement.closest('.sub-menu.visible');

            // Check if the focused element is inside .sub-menu
            if (subMenu) {
                const button = subMenu.previousElementSibling;
                button.focus();
                // Close the submenu
                button.setAttribute('aria-expanded', 'false');
                subMenu.classList.add('hidden');
                subMenu.classList.remove('visible');

                subMenu.setAttribute('aria-hidden', 'true');

                const buttonText = button.querySelector('.dropdown-button-content');
                if (buttonText) {
                    buttonText.textContent = '+';
                }
            }
        }

        //* Enter
        //* When focus is on a menuitem that has a submenu, opens the submenu and places focus on its first item.
        //* Otherwise, activates the item and closes the menu.
        if (event.key === 'Enter' ) {
            // Check if the focused element has a submenu
            if (focusedElement.classList.contains('dropdown-button')) {
                const ariaExpanded = focusedElement.getAttribute('aria-expanded');
                const ariaControls = focusedElement.getAttribute('aria-controls');
                const submenu = document.getElementById(ariaControls);

                if (submenu) {
                    if (ariaExpanded === 'false') {
                        // Open the submenu
                        focusedElement.setAttribute('aria-expanded', 'true');
                        submenu.classList.add('visible');
                        submenu.classList.remove('hidden');

                        submenu.setAttribute('aria-hidden', 'false');

                        const buttonText = focusedElement.querySelector('.dropdown-button-content');
                        if (buttonText) {
                            buttonText.textContent = '-';
                        }

                        // Move focus to the first item in the submenu
                        const firstSubmenuItem = submenu.querySelector('[role="menuitem"]');
                        if (firstSubmenuItem) {
                            firstSubmenuItem.focus();
                        }
                    } else {
                        // Close the submenu
                        focusedElement.setAttribute('aria-expanded', 'false');
                        submenu.classList.add('hidden');
                        submenu.classList.remove('visible');

                        submenu.setAttribute('aria-hidden', 'true');

                        const buttonText = focusedElement.querySelector('.dropdown-button-content');
                        if (buttonText) {
                            buttonText.textContent = '+';
                        }
                    }
                }
            }
        }

        //* Home: If arrow key wrapping is not supported, moves focus to the first item in the current menu or menubar.
        //* End: If arrow key wrapping is not supported, moves focus to the last item in the current menu or menubar.
        if (focusedElement.closest('.sub-menu')) {
            const menuItems = Array.from(focusedElement.closest('.sub-menu').querySelectorAll('[role="menuitem"]'));
    
            if (event.key === 'Home') {
                event.preventDefault();
                menuItems[0].focus();
            }
    
            if (event.key === 'End') {
                event.preventDefault();
                menuItems[menuItems.length - 1].focus();
            }
        }
    });
});
  1. I have used some Chrome extensions like “Accessibility Insights for Web” and “WAVE”.
  2. I have used some articles from https://www.w3.org/WAI/ARIA/apg/ as a guideline.
  3. Manual testing by using TAB and other keys to test the implementation.
  4. I have not tried automated testing websites since my website is being developed locally and is not on a server.

Permissions to Create GitHub Repo via API

I am creating a web application to create a private Github repo for the user. I followed the instructions to create a Github App and use it to create a UAT via these instructions.
In my Github App, I do not see permissions for repo which is required according to this doc.

I have enabled read and write Repository permissions for Administration, Contents, Custom Properties, Environments, and Projects. However, my POST request to /user/repos with the user’s UAT returns an error response:

{
  "message": "Resource not accessible by integration",
  "documentation_url": "https://docs.github.com/rest/repos/repos#create-a-repository-for-the-authenticated-user",
  "status": "403"
}

How can I fix my permissions to create a private repository for the user via UAT?

Issue with react-native-keychain in React Native 0.72.2 (App Crashes After Build)

I am facing an issue with the react-native-keychain library in my React Native project running on version 0.72.2. I have installed the latest version of react-native-keychain (9.2.2). The app builds successfully without any errors, but when I try to open the app after installation, it crashes immediately.

Here are the relevant environment details:

Gradle version: 8.0.1
Node version: 22.12.0
Java version: 18.0.2.1
From my debugging efforts, it seems the issue is specifically caused by the react-native-keychain library. However, there are no specific errors being logged in the build process, making it challenging to pinpoint the exact problem.

Here’s what I’ve tried so far:

Ensured the library was linked correctly.
Ran npx react-native-clean-project to clear any cache issues.
Verified the installation steps provided in the library documentation.
Checked for any configuration mismatch in the android/build.gradle or app/build.gradle files.
Despite these efforts, the issue persists. I suspect it might be related to compatibility between the library and my environment setup.

Has anyone encountered a similar issue or can provide guidance on resolving this? Any suggestions or troubleshooting steps would be greatly appreciated.

Difference between useRef vs document.getElementById to focus an input

I’m following a React tutorial on Youtube and currently have this React code:

import { useRef } from 'react';

const AddItem = ({ newItem, setNewItem, handleSubmit }) => {
    const inputRef = useRef();

    return (
        <form className="addForm" onSubmit={handleSubmit}>
            <input
                ref={inputRef}
                id="addItem"
                type="text"
                value={newItem}
                onChange={(e) => setNewItem(e.target.value)}
            />
            <button
                type="submit"
                onClick={() => inputRef.current.focus()}
                // onClick={() => document.getElementById('addItem').focus()} // What does this do differently?
            >
            </button>
        </form>
    );
};

export default AddItem;

I’m using useRef() along with onClick={() => inputRef.current.focus()} to make sure the text input is focused after clicking the button.

I can do the same thing without the need for the useRef hook by using onClick={() => document.getElementById('addItem').focus()}.

Is there a benefit to using the useRef method over the getElementById method?

Can’t write image to given path using graphicsmagick javascript library

  resizeImage(image: string, destPath: string, [w, h]: ImageDimensions) {
    return new Promise((resolve, reject) => {
      gm(image)
        .resize(w, h, "!")
        .noProfile()
        .write(destPath, (err) => {
          if (err) return reject(err);
          return resolve(destPath);
        });
    });
  }

so i’m trying to resize the image and write it to destPath.

the image parameter is F:hobbygokz-imagesimagesbkz_measuremap.jpg and destPath is F:hobbygokz-imagespublicfullbkz_measuremap.jpg in my case.

but i got this error said Command failed: gm convert: Unable to open file (F:hobbygokz-imagespublicfullbkz_measuremap.jpg).

i can make sure the source image and destination path both exist.

how can i fix this?

How to use Posthog to capture pageview events with React Router?

I have the following SPA that uses react router:

ReactDOM.createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <Providers>
      <BrowserRouter>
        <Routes>
          <Route element={<ProtectedRoutes />}>
            <Route path="/dashboard" element={<MainPage />} />
            <Route path="/dashboard/setup" element={<SetupPage />} />
            <Route path="/dashboard/project/:projectId" element={<ProjectPage />} />
          </Route>
          <Route path="/admin" element={<ProtectedRoutes admin />}>
            <Route path="" element={<div>you are admin</div>} />
            <Route path="users" element={<UsersPage />} />
            <Route path="data/view" element={<DataViewPage />} />
            <Route path="tasks" element={<TasksPage />} />
          </Route>
          <Route element={<PublicOnlyRoutes redirectTo="/dashboard?redirect=true" />}>
            <Route path="/login" element={<LoginPage />} />
          </Route>
          <Route path="/" element={<HomePage />} />
          <Route
            path="/demo"
            element={<DemoComponent message="Sample message" name="User" />}
          />
        </Routes>
      </BrowserRouter>
    </Providers>
  </StrictMode>,
);

I would like to use Posthog’s event capturing with this to track when users navigate around the application. Like this:

function PostHogIdentifier() {
  const location = useLocation();

  // Track pageviews
  useEffect(() => {
    if (posthog) {
      console.log("Capturing pageview", window.location.href);
      posthog.capture(
        '$pageview',
        {
          '$current_url': window.location.href,
        }
      )
    }
  }, [location])
  
  return null;
}

But, I can’t do this because the useLocation hook must be run inside of the BrowserRouter. And I’m not sure how to do this since the BrowserRouter only supports Route and Routes child components.

In nodejs, how to get AST representation from the result of `script.runInContext` (loseless)

I am doing something like

let p = `(function (X) {
  var q = 0;
  for (; q < 5; ) {
    // do some stuff
    anotherfunc = function (a) {
      while (X === "somestring") {
        X += "_";
      }
    };
    q++;
  }
  return { anotherfunc: anotherfunc };
})("some arg");
`;

const vm = require("vm");
const script = new vm.Script(p);
const context = vm.createContext({});
const result = script.runInContext(context);

console.log(result);

I get { anotherfunc: ƒ anotherfunc() } printed, but if I use JSON.stringify(result) I get "{}"

I want to get something like

{ 
    anotherfunc: function (a) {
      while (X === "somestring") {
        X += "_";
      }
    };
}

in order to pass it to acorn.parse and get and AST representation.

Is there a way to make script.runInContext save the result to file for example, or have acorn parse the result which is not a string?

jest has different behavior for tests

I have two functions. One for creating a websocket server and one for creating a websocket client based on this protocol called ocpp, using a library called ocpp-ts.

Client:

import {BootNotificationRequest, BootNotificationResponse, OcppClient, OcppError} from "ocpp-ts";

export function createClient(port: number) {
    const chargingPointSimple = new OcppClient('CP1111');
    chargingPointSimple.on('error', (err: Error) => {
        console.log(err.message);
    });
    chargingPointSimple.on('close', () => {
        console.log('Connection closed');
    });

    chargingPointSimple.on('connect', async () => {
        const boot: BootNotificationRequest = {
            chargePointVendor: 'eParking',
            chargePointModel: 'NECU-T2',
        };

        try {
            const bootResp: BootNotificationResponse = await chargingPointSimple.callRequest('BootNotification', boot);
            if (bootResp.status === 'Accepted') {
                console.log('Bootnotification accepted');
            }
        } catch (e) {
            if (e instanceof Error || e instanceof OcppError) {
                console.error(e.message);
            }
        }
    });
    chargingPointSimple.connect(`ws://localhost:${port}/`);
    return chargingPointSimple;
}

if (require.main === module) {
    createClient(9220);
}

Server:

import {
    OcppServer, OcppClientConnection, BootNotificationRequest, BootNotificationResponse,
} from 'ocpp-ts';

export function createServer(port: number): OcppServer {
    const centralSystemSimple = new OcppServer();
    centralSystemSimple.listen(9220);
    centralSystemSimple.on('connection', (client: OcppClientConnection) => {
        console.log(`Client ${client.getCpId()} connected`);
        client.on('close', (code: number, reason: Buffer) => {
            console.log(`Client ${client.getCpId()} closed connection`, code, reason.toString());
        });

        client.on('BootNotification', (_: BootNotificationRequest, cb: (response: BootNotificationResponse) => void) => {
            const response: BootNotificationResponse = {
                status: 'Accepted',
                currentTime: new Date().toISOString(),
                interval: 60,
            };
            cb(response);
        });
    });
    return centralSystemSimple;
}

if (require.main === module) {
    createServer(9220);
}

If I run these servers individually on seperate terminals, behavior works as expected. I get a message that I expect.

However when I run the servers in this test using npx jest:

/**
 * @jest-environment node
 */
import {
    BootNotificationRequest,
    BootNotificationResponse,
    OcppClient,
    OcppClientConnection,
    OcppError,
    OcppServer
} from "ocpp-ts"
import {createServer} from "./server";
import {createClient} from "./client";
const sleep = (ms: number | undefined) => new Promise((resolve) => setTimeout(resolve, ms));

describe("simple test", () => {
    let centralSystemSimple: OcppServer
    // let expressServer: ApiServer
    let client: OcppClient
    const wsPort: number = 9220
    // const apiPort = 1340
    // let wsAgent: WSChain

    beforeAll(async () => {
        centralSystemSimple = createServer(wsPort)
    })

    it("should work", async () => {
        createClient(wsPort)
    })

    afterAll(async () => {
        // await sleep(9999)
    })
})

I get this error (when trying to connect the client):

TypeError: server.listenerCount is not a function
    at parserOnIncoming (node:_http_server:1045:26)
    at HTTPParser.parserOnHeadersComplete (node:_http_common:117:17)
    at socketOnData (node:_http_server:836:22)
    at Socket.emit (node:events:507:28)
    at addChunk (node:internal/streams/readable:559:12)
    at readableAddChunkPushByteMode (node:internal/streams/readable:510:3)
    at Socket.Readable.push (node:internal/streams/readable:390:5)
    at InternalSocket.onStreamRead [as onread] (node:internal/stream_base_commons:189:23)
    at InternalSocket.readData (/Users/brian.yeh/WebstormProjects/occp_test/node_modules/mitm/lib/internal_socket.js:168:8)
    at InternalSocket.emit (node:events:507:28)

Relevant git repo is here if you would like to experiment:

https://github.com/pyrofolium/ocpp_test

What’s going on? Why different behavior?

Javascript button isn’t working on a WordPress HTML code?

Using the code from a different answer:

    const field = document.querySelector('#solution');
const link = document.querySelector('#link');

document.querySelector('#mybutton').addEventListener('click', (event) => {
    link.style.display = (field.value.toLowerCase() === 'answer')
        ? 'block'
        : 'none';
});
#link {
    display: none;
}

.a-as-button {
    display: block;
    width: 115px;
    height: 25px;
    background: #4E9CAF;
    padding: 10px;
    text-align: center;
    border-radius: 5px;
    color: white;
    font-weight: bold;
}
<label for="solution"> Solution:</label>
<input type="text" id="solution" name="solution" placeholder="Enter Code Here"></input>
<button id='mybutton' type="button">Enter</button>

<a id='link' class='a-as-button' href="www.website.com/nextpage.html">
    Next Step
</a>

I’ve tried inputting this on a wordpress site, but can’t get it to work successfully, even though it runs fine on stackoverflow

My code test

Can anyone tell me if I’m missing something in implementing it?

The intended result is:

[Some text written puzzle, that the solution is a text string]

[Text field][Enter button]

~Upon Entry of Correct Text String, A New Button Appears~ [New Button, Linking to the Next Webpage]

eslint persistent error despite corrections

I’m working on this project made with Next.js, typescript and Auth0 for authentication.

I’ve made sure the variables from the useState are utilized, but the eslint fails everytime I run it. Is there a config issue here?

You can review my code below. I’ve shortened it for readability.

'use client';
    import Image from 'next/image';
    import { useState } from 'react';
    import SignupForm from './SignupForm';
    import { FormsToggleProps } from './Types';

    const Login = ({ showLogin, setShowLogin }: FormsToggleProps) => {

      const [email, setEmail] = useState('');
      const [password, setPassword] = useState('');
      const [error, setError] = useState('');

      const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        try {
          const res = await fetch('/api/auth/login', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({ email, password }),
          });

          if (res.ok) {
            console.log('Login successful');
            // Handle successful login
          } else {
            const data = await res.json();
            setError(data.message || 'Login failed');
          }
        } catch (err) {
          setError(err instanceof Error ? err.message : 'Something went wrong');
        }
      };

      return (
        <section className="bg-gray-50 dark:bg-gray-900">
            <div className="w-full rounded-lg bg-white shadow sm:max-w-md md:mt-0 xl:p-0 dark:border dark:border-gray-700 dark:bg-gray-800">
              <div className="space-y-4 p-6 sm:p-8 md:space-y-6">
                {showLogin ? (
                  <>
                    <h1 className="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
                      Sign in to your account
                    </h1>
                    <form className="space-y-4 md:space-y-6" onSubmit={handleSubmit}>
                      <div>
                        <label
                          htmlFor="email"
                          className="mb-2 block text-sm font-medium text-gray-900 dark:text-white"
                        >
                          Your email
                        </label>
                        <input
                          type="email"
                          name="email"
                          id="email"
                          value={email}
                          onChange={(e) => setEmail(e.target.value)}
                          required
                        />
                      </div>
                      <div>
                        <label
                          htmlFor="password"
                          className="mb-2 block text-sm font-medium text-gray-900 dark:text-white"
                        >
                          Password
                        </label>
                        <input
                          type="password"
                          name="password"
                          id="password"
                          value={password}
                          onChange={(e) => setPassword(e.target.value)}
                          required
                        />
                      </div>
                      {error && <p className="text-red-500">{error}</p>}
                      <button
                        type="submit"
                        className="focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800 w-full rounded-lg bg-blue-600 px-5 py-2.5 text-center text-sm font-medium text-white hover:bg-blue-800 focus:outline-none focus:ring-4">

This is the eslintrc.json file with the current configuration.

//.eslintrc.json
        {
          "env": {
            "browser": true,
            "es2021": true
          },
          "extends": [
            "eslint:recommended",
            "plugin:@next/next/recommended",
            "plugin:prettier/recommended"
          ],
          "parserOptions": {
            "ecmaFeatures": {
              "jsx": true
            },
            "ecmaVersion": 12,
            "sourceType": "module"
          },
          
          "rules": {
            "prettier/prettier": ["error", { "endOfLine": "auto" }],
            "react/react-in-jsx-scope": "off"
          }
        }

This is the persistent error. I have tried updating the code several times making sure the variables are utilized, but the console keeps bugging with the same error code:

$ git commit -m 'update Login'
        ✔ Backed up original state in git stash (63a4bd8)
        ✔ Hiding unstaged changes to partially staged files...
        ⚠ Running tasks for staged files...
          ❯ package.json — 1 file
            ❯ *.{js,jsx,ts,tsx} — 1 file
              ✖ eslint --fix [FAILED]
              ◼ prettier --write
        ↓ Skipped because of errors from tasks.
        ↓ Skipped because of errors from tasks.
        ✔ Reverting to original state because of errors...
        ✔ Cleaning up temporary files...
        
        ✖ eslint --fix:
        8:17  error  'setEmail' is assigned a value but never used     @typescript-eslint/no-unused-vars
           9:20  error  'setPassword' is assigned a value but never used  @typescript-eslint/no-unused-vars
          10:10  error  'error' is assigned a value but never used        @typescript-eslint/no-unused-vars
          31:14  error  'error' is defined but never used                 @typescript-eslint/no-unused-vars
        
        ✖ 4 problems (4 errors, 0 warnings)
        
        husky - pre-commit script failed (code 1)

Query Invalidation: why i have to refresh the page to get the results fetching the habitats or delete the habitat?

So this is the first part is from a component where i create new habitats using tanstack V5 im passing queryKey [‘habitats’]

const createHabitatMutation = useMutation({
    mutationFn: habitatService.createHabitat,
    onSuccess: () => {
      toast({
        title: 'Habitat created successfully!',
        status: 'success',
        duration: 5000,
        isClosable: true,
      });
      queryClient.invalidateQueries({ queryKey: ['habitats'] }) 
      onClose();
    },
    onError: (error) => {
      toast({
        title: 'Error creating habitat',
        description: error.message || 'Please try again later.',
        status: 'error',
        duration: 5000,
        isClosable: true,
      });
    },

the next part is from another components to retrieve and delete habitat im using invalidates query with the same key [‘habitats’]

 const { data: habitats = [], isLoading, isError } = useQuery({
    queryKey: ['habitats'],
    queryFn: () => habitatService.getAllHabitats(),
    onError: (error) => {
      toast({
        title: 'Error fetching habitats',
        description: error.message,
        status: 'error',
        duration: 5000,
        isClosable: true,
      });
    },
  });



 const deleteHabitatMutation = useMutation({
mutationFn: habitatService.deleteHabitat,
onSuccess: () => {
  queryClient.invalidateQueries({ queryKey: ['habitats'] }) 
  toast({
    title: 'Habitat deleted',
    description: 'The habitat was successfully deleted.',
    status: 'success',
    duration: 3000,
    isClosable: true,
  });
},
onError: (error) => {
  toast({
    title: 'Error deleting habitat',
    description: error.message,
    status: 'error',
    duration: 5000,
    isClosable: true,
  });
},

The behavior I’m looking for is when I create data, it should be displayed immediately without refreshing the page. The same applies to deleting data—it should be removed instantly without needing to refresh

Query Invalidation: i need to refresh the page to get the results fetching the habitats and delete the habitat

So this is the first part is from a component where i crate new habitats using tanstack V5 im passing queryKey [‘habitats’]

const createHabitatMutation = useMutation({
    mutationFn: habitatService.createHabitat,
    onSuccess: () => {
      toast({
        title: 'Habitat created successfully!',
        status: 'success',
        duration: 5000,
        isClosable: true,
      });
      queryClient.invalidateQueries({ queryKey: ['habitats'] }) 
      onClose();
    },
    onError: (error) => {
      toast({
        title: 'Error creating habitat',
        description: error.message || 'Please try again later.',
        status: 'error',
        duration: 5000,
        isClosable: true,
      });
    },

the next part is from another components to retrieve and delete habitat im using invalidates query with the same key [‘habitats’]

     const { data: habitats = [], isLoading, isError } = useQuery({
    queryKey: ['habitats'],
    queryFn: () => habitatService.getAllHabitats(),
    onError: (error) => {
      toast({
        title: 'Error fetching habitats',
        description: error.message,
        status: 'error',
        duration: 5000,
        isClosable: true,
      });
    },
  });



 const deleteHabitatMutation = useMutation({
mutationFn: habitatService.deleteHabitat,
onSuccess: () => {
  queryClient.invalidateQueries({ queryKey: ['habitats'] }) 
  toast({
    title: 'Habitat deleted',
    description: 'The habitat was successfully deleted.',
    status: 'success',
    duration: 3000,
    isClosable: true,
  });
},
onError: (error) => {
  toast({
    title: 'Error deleting habitat',
    description: error.message,
    status: 'error',
    duration: 5000,
    isClosable: true,
  });
},