How do i resolve the mysqli_num_rows error in php

I am getting the following error on my browser for my php
Here’s the error: Fatal error: Uncaught TypeError: mysqli_num_rows(): Argument #1 ($result) must be of type mysqli_result, bool given in C:xampphtdocsprojectsignup.php:13 Stack trace: #0 C:xampphtdocsprojectsignup.php(13): mysqli_num_rows(false) #1 {main} thrown in C:xampphtdocsprojectsignup.php on line 13

line 13 of php code: $numExistRows = mysqli_num_rows($result);

My php code:

<?php
$showAlert = false;
$showError = false;
if($_SERVER["REQUEST_METHOD"] == "POST"){
  include 'partials/_dbconnect.php';
  $username = $_POST["Username"];
  $password = $_POST["Password"];
  $cpassword = $_POST["CPassword"];
  //$exists=false;
  //Check whether username exists or not
  $existSql = "SELECT * FROM `users` WHERE username = '$username'";
  $result = mysqli_query($conn, $existSql);
  $numExistRows = mysqli_num_rows($result);
  if($numExistRows> 0){
    //$exists = true;
    $showError = "Username already exists.";
  }
  else{
    //$exists = false;
    if(($password == $cpassword)){
      $hash = password_hash($password, PASSWORD_DEFAULT);
      $sql = "INSERT INTO `users` (`Username`, `Password`, `Date`) VALUES ('$username', '$hash', current_timestamp());";
      $result = mysqli_query($conn, $sql);
      if($result){
        $showAlert = true;
      }
    }
    else{
      $showError = "Passwords don't match.";
    }
  }
}


?>

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>SignUp</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
  </head>
  <body>
    <?php require 'partials/_nav.php'  ?>
    <?php
    if($showAlert){
    echo '<div class="alert alert-success alert-dismissible fade show" role="alert">
          <strong>Success!</strong> Your account has been created.
          <button type="button" class="close" data-dismiss="alert" aria-label="Close">
          <span aria-hidden="true">&times;</span>
          </button>
          </div>';
        }
    if($showError){
      echo '<div class="alert alert-danger alert-dismissible fade show" role="alert">
            <strong>Sorry!</strong> '.$showError.'
            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                <span aria-hidden="true">&times;</span>
            </button>
            </div>';
          }
    ?>
    <div class="container">
        <h1 class="text-center">Create an Account</h1>
        <form action="signup.php" method="post">
        <div class="form-group">
            <label for="Username">Username</label>
            <input type="text" maxlength="15" class="form-control" id="Username" name="Username" aria-describedby="emailHelp">
        </div>
        <div class="form-group">
            <label for="Password">Password</label>
            <input type="password" maxlength="15" class="form-control" id="Password" name="Password">
        </div>
        <div class="form-group">
            <label for="CPassword">Confirm Password</label>
            <input type="password" maxlength="15" class="form-control" id="CPassword" name="CPassword">
            <small id="emailHelp" class="form-text text-muted">Make sure to type the same password.</small>
        </div>
        <button type="submit" class="btn btn-primary">SignUp</button>
        </form>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js" integrity="sha384-oBqDVmMz9ATKxIep9tiCxS/Z9fNfEXiDAYTujMAeBAsjFuCZSmKbSSUnQlmh/jp3" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-IDwe1+LCz02ROU9k972gdyvl+AESN10+x7tBKgc9I5HFtuNz0wWnPclzo6p9vxnk" crossorigin="anonymous"></script>
  </body>
</html>

partials/_dbconnect.php code here:

<?php
$server = "localhost";
$name = "root";
$email = "";
$number = "";
$subject = "";
$txtMessage = "";
$database = "contact";
$conn = mysqli_connect($server, $name, $email, $number, $subject, $txtMessage, $database);
if (!$conn){
//    echo "success";
//}
//else{
    die("Error".mysqli_connect_error());
}
?>

I tried doing all the possible changes from my side but it didn’t help.

mandatory selection from drop down box

below is the function.

If you go to the very end to the comment “// mandatory selection from drop down box” and look at those next 5 lines of code, that’s where I am trying to make that the selection from a drop down box needs to be made before a form can be submitted.
However, it is not working.

Can someone please help with concrete code sugestion?

function register_user(type) {
"use strict";
var capthca, user_login_register, user_email_register, user_pass, user_pass_retype, nonce, ajaxurl, new_user_type;
/* 1- topbar
 * 2- widget
 * 3- shortcode
 * 4- modal !?
 * 5 -mobile
 */

capthca = '';

ajaxurl = ajaxcalls_vars.admin_url + 'admin-ajax.php';
jQuery('#register_message_area_topbar').empty().append('<div class="login-alert">' + control_vars.procesing + '</div>');

if (type === 1) {
    if (control_vars.usecaptcha === 'yes') {
        capthca = grecaptcha.getResponse(
                widgetId1
                );
    }

    user_login_register = jQuery('#user_login_register_topbar').val();
    user_email_register = jQuery('#user_email_register_topbar').val();
    nonce = jQuery('#security-register-topbar').val();
    if (ajaxcalls_vars.userpass === 'yes') {
        user_pass = jQuery('#user_password_topbar').val();
        user_pass_retype = jQuery('#user_password_topbar_retype').val();
    }


    new_user_type = jQuery('#new_user_type_topbar').val();

    if (!jQuery('#user_terms_register_topbar').is(":checked")) {
        jQuery('#register_message_area_topbar').empty().append('<div class="login-alert">' + control_vars.terms_cond + '</div>');
        return;
    }
} else if (type === 2) {

    if (control_vars.usecaptcha === 'yes') {
        capthca = grecaptcha.getResponse(
                widgetId3
                );
    }

    user_login_register = jQuery('#user_login_register_wd').val();
    user_email_register = jQuery('#user_email_register_wd').val();
    nonce = jQuery('#security-register').val();
    if (ajaxcalls_vars.userpass === 'yes') {
        user_pass = jQuery('#user_password_wd').val();
        user_pass_retype = jQuery('#user_password_wd_retype').val();
    }

    new_user_type = jQuery('#new_user_type_wd').val();

    if (!jQuery('#user_terms_register_wd').is(":checked")) {
        jQuery('#register_message_area_wd').empty().append('<div class="login-alert">' + control_vars.terms_cond + '</div>');
        return;
    }
} else if (type === 3) {

    if (control_vars.usecaptcha === 'yes') {
        capthca = grecaptcha.getResponse(
                widgetId4
                );
    }

    user_login_register = jQuery('#user_login_register').val();
    user_email_register = jQuery('#user_email_register').val();
    nonce = jQuery('#security-register').val();
    if (ajaxcalls_vars.userpass === 'yes') {
        user_pass = jQuery('#user_password').val();
        user_pass_retype = jQuery('#user_password_retype').val();
    }

    new_user_type = jQuery('#new_user_type').val();

    if (!jQuery('#user_terms_register_sh').is(":checked")) {
        jQuery('#register_message_area').empty().append('<div class="login-alert">' + control_vars.terms_cond + '</div>');
        return;
    }
} else if (type === 5) {

    if (control_vars.usecaptcha === 'yes') {
        capthca = grecaptcha.getResponse(
                widgetId2
                );
    }
    user_login_register = jQuery('#user_login_register_mobile').val();
    user_email_register = jQuery('#user_email_register_mobile').val();
    nonce = jQuery('#security-register-mobile').val();
    if (ajaxcalls_vars.userpass === 'yes') {
        user_pass = jQuery('#user_password_mobile').val();
        user_pass_retype = jQuery('#user_password_mobile_retype').val();
    }

    new_user_type = jQuery('#new_user_type_mobile').val();




    if (!jQuery('#user_terms_register_mobile').is(":checked")) {
        jQuery('#register_message_area_mobile').empty().append('<div class="login-alert">' + control_vars.terms_cond + '</div>');
        return;
    }
}

// mandatory selection from drop down box
***if (!jQuery('#new_user_type_topbar').val=='something') {
jQuery('#register_message_area_topbar').empty().append('<div class="login-alert">Mandatory text</div>');
return;
}***

 ...
 ...
 ...
            }
        },
        error: function (errorThrown) {
        }
    });
}

React.Js – Warning: Each child in a list should have a unique “key” prop

I have a post page, where the user fetches data about a post with comments.

The user can create/delete comments and post.

However when the user deletes a comment I get his error:

Warning: Each child in a list should have a unique "key" prop.

Check the render method of `PostDetail`. See https://reactjs.org/link/warning-keys for more information.
PostDetail@webpack-internal:///./pages/post/[id].tsx:21:88
div
App@webpack-internal:///./pages/_app.tsx:31:38
PathnameContextProviderAdapter@webpack-internal:///./node_modules/next/dist/shared/lib/router/adapters.js:62:34
ErrorBoundary@webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/dist/client.js:301:63
ReactDevOverlay@webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/dist/client.js:850:908
Container@webpack-internal:///./node_modules/next/dist/client/index.js:61:1
AppContainer@webpack-internal:///./node_modules/next/dist/client/index.js:171:25
Root@webpack-internal:///./node_modules/next/dist/client/in

dex.js:346:37

I do not understand what the problem is, Every Comment has its on key prop when it gets “loaded”.

This is my PostDetail.tsx page:

import React, { useCallback, useEffect, useState } from 'react'
import Image from 'next/image'
import Link from 'next/link'
import styles from '../../styles/Post.module.css';
import formStyle from '../../styles/HomePage.module.css';
import { useRouter } from 'next/router';
import Post from '@/components/Post';
import { Comment } from '@/components/Comment';


interface CommentData{
    '_id': string,
    'creator': {
        'username': string,
        '_id': string
    },
    'comment': string,
    'isOwner': boolean,
    'createdAt': string,
}

interface PostData {
    'post_creator': {
        'username': string,
        '_id': string
    },
    '_id': string,
    'post_content': string,
    'createdAt': string,
    'comments': {
        '_id': string,
        'username': string
    }
    'likes': [],
    'replies': []
}

const PostDetail = () => {
    const [newComment, setNewComment] = useState<any>();
    const [isLoading, setIsLoading] = useState<boolean>(false);
    const [postData, setPostData] = useState<PostData>();
    const [comments, setComments] = useState<any>([]);

    const userData: any = localStorage.getItem('userData');
    const parsedData = JSON.parse(userData)
    const userID = parsedData.user_id

    const router = useRouter();
    const changeFormHeight = () => {

        let textArea = (document.getElementById("NewPostForm") as HTMLTextAreaElement);
        const numOfRows = textArea.value.split('n').length;        

        if(textArea.value == ""){
            textArea.style.height = "80px";
        }

        switch (true) {
            case (numOfRows >= 7):
                textArea.style.height = "200px";
                break;
            case (numOfRows >= 3):
                textArea.style.height = "150px";
                break;
            default:
                textArea.style.height = "80px";
                break;
        }

        setNewComment(textArea.value)
    }
    

    const onSubmit = async (event: React.FormEvent<HTMLFormElement>): Promise<void> => {
        event.preventDefault();

        createNewComment();

    }

    const createNewComment = async () => {
        console.log(comments)
        const payload = { 
            'token': localStorage.getItem('token'),
            'newComment': encodeURIComponent(newComment)
        }
        
        const body = JSON.stringify(payload);
        try {
            const response = await fetch(`http://localhost:8888/api/post/${postData?._id}/newComment`, {
                method: "POST",
                headers: {
                "Content-Type": "application/json",
                "Authorization": 'Bearer ' + payload.token
                },
                body: body,
            })
    
            const newCommentData: CommentData = await response.json();
    
            // set the isOwner value based on the current user's ID
            const userData: any = localStorage.getItem('userData');
            const parsedData = JSON.parse(userData);
            const userID = parsedData.user_id;
            newCommentData.isOwner = userID === newCommentData.creator._id;
    
            setComments((prevComments: CommentData[]) => [...prevComments, newCommentData]);    

            let textArea = (document.getElementById("NewPostForm") as HTMLTextAreaElement);
            textArea.value = "";
            textArea.style.height = "80px";
    
            setNewComment("");    
            console.log(comments)

        } catch (error) {
            console.log(error);
        }
    }
    
    const fetchPostData = async (postID: any) => {
        setIsLoading(true);

        const payload = { 
            'token': localStorage.getItem('token'),
        }

        const response = await fetch(`http://localhost:8888/api/post/post/${postID}`, {
            method: "GET",
            headers: {
                "Authorization": 'Bearer ' + payload.token
            }
        })


        const data: PostData = await response.json();
        setIsLoading(false);
        setPostData(data);
        setComments(data.comments)
        console.log(data.comments)
    }

    const getPostID = useCallback(() => {
        return router.query.id
    }, [router.query.id])
    
    
    useEffect(() => {
        const postID = getPostID();
    
        if (postID) {
            fetchPostData(postID);
        }
    }, [getPostID]);

    const renderComment = (_id:string, creator:any, comment:string, createdAt:string, postID:any) => {
        const isOwner = userID === creator._id
        return(
            <>
            <Comment
                    key={_id}
                    _id={_id}
                    creator={creator}
                    comment={comment}
                    isOwner={isOwner}
                    createdAt={createdAt}
                    postID={postID}
                />
            </>
        )
    }
    return (
        <>
            {postData && (
                <Post 
                    key={postData._id}
                    _id={postData._id}
                    post_creator={postData.post_creator} 
                    post_content={postData.post_content} 
                    likes={postData.likes}
                    replies={postData.replies}
                    createdAt={postData.createdAt}
                    type='DETAIL'
                    isOwner={userID === postData.post_creator._id}
                />
            )}

            <div className={`${formStyle.NewPostContainer} ${formStyle.BorderTop}`}>
                <h2 className={formStyle.NewFormTitle}>Create new comment: </h2>
                <form className={formStyle.Form} onSubmit={onSubmit}>
                    <textarea id='NewPostForm' onChange={changeFormHeight}/>
                    <div className={`${formStyle.FormToolBar} ${formStyle.Flex_reverse}`}>
                        <button className={formStyle.PostButton}>Post new comment</button>
                    </div>
                </form>
            </div>

            { !isLoading && comments.map((comment: CommentData) => (
                renderComment(comment._id, comment.creator, comment.comment, comment.createdAt, postData?._id)              
            ))}

        </>
    )
}

export default PostDetail

And this is my Comment.tsx:

    import Image from 'next/image'
import Link from 'next/link'
import { useRouter } from 'next/router'
import React from 'react'
import styles from '../styles/Comment.module.css'

interface CommentProps{
    '_id': string,
    'creator': {
        'username': string,
        '_id': string
    },
    'comment': string,
    'isOwner': boolean,
    'createdAt': string,
    'postID': string
}

export const Comment = ({ _id, creator, comment, isOwner, createdAt, postID } : CommentProps) => {

    const likeButtonHeight = !isOwner ? styles.fullHeight : '';
    const deletButtonHeight = isOwner ? styles.fullHeight  : '';
    const router = useRouter();

    function timeDifference(current: any, previous: any): string {
        const intervals = {
            year: 31536000,
            month: 2592000,
            day: 86400,
            hour: 3600,
            minute: 60,
            second: 1,
        };
        const secondsElapsed = Math.floor((current - previous) / 1000);
        for (const [key, value] of Object.entries(intervals)) {
            const count = Math.floor(secondsElapsed / value);
            if (count >= 1) {
                return count === 1 ? `1 ${key} ago` : `${count} ${key}s ago`;
            }
        }
        return "Just now";
    }
    
    let timestamp = timeDifference(new Date(), new Date(createdAt));

    const deleteComment = async() => {
        
        const payload = { 
            'token': localStorage.getItem('token'),
        }
    
        await fetch(`http://localhost:8888/api/post/${postID}/comment/${_id}`, {
            method: "DELETE",
            headers: {
                "Authorization": 'Bearer ' + payload.token
            }
        })

        router.reload()
    }
    

    return (
        <div key={_id}  className={styles.Comment}>
            <h1>{_id}</h1>
            <Link href={`/profile/${creator._id}`} className={styles.CommentLeftBody}>
                <Image className={styles.UserImage}  src='/images/user_icon.png' width="512" height="512" alt='User profile image'/>
                <div>
                    <h2 className={styles.UserName}>{creator.username}</h2>
                </div>

            </Link>

            <div className={styles.CommentBody}>
                <p>
                    {decodeURIComponent(comment)}
                </p>
                <h3 className={styles.TimeStamp}>{timestamp}</h3>
            </div>
            
            <div className={styles.CommentToolbar}>
                { !isOwner &&
                    <button className={`${styles.LikeButton} ${likeButtonHeight}`}>
                        <i className="fa-solid fa-heart"></i>
                    </button>
                }
                
                { isOwner && 
                    <button onClick={deleteComment}  className={`${styles.DeleteButton} ${deletButtonHeight}`}>
                        <i className="fa-solid fa-trash-can"></i>
                    </button>
                }
            </div>
        </div>
    )
}

Add Listing to Cart

I’m having trouble adding items to a cart. With one set of code, I can add new items, but in doing so, it’ll overwrite what was there previously. With another set of code, I can add multiple items, but they all come in as undefined.

localStorage.js

export const getCartItems = () => {
    const cartItems = localStorage.getItem('cartItems')
        ? JSON.parse(localStorage.getItem('cartItems'))
        : [];
    return cartItems;
};

export const setCartItems = (cartItems) => {
    localStorage.setItem('cartItems', JSON.stringify(cartItems));
};

main.js

if(document.querySelector('#cart-list-container')) {
    const cartList = document.getElementById('cart-list-container');
    if(cartItems.length === 0) {
        cartList.innerHTML = `
            <h3>Cart is Empty. Click <a href="/"><b>HERE</b></a> to Start Shopping!'</h3?
        `;
    }
    else {
        cartList.innerHTML = `
            ${cartItems.map(item => `
                <li>
                    <ul class="item-details">
                        <li>
                            <a href="/listing/${item.slug}"}>
                                <div class="cart-img">
                                    <img src="/images/${item.image_main}" alt="${item.name}">
                                </div>
                            </a>
                        </li>
                        <li class="cart-name">
                            <a href="/listing/${item.slug}"}>${item.name}</a>
                        </li>
                        <li>
                            Qty: 
                            <select class="qty-select" id="">
                                ${
                                    [...Array(item.count_in_stock).keys()].map((x) => item.qty === x + 1
                                    ? `<option selected value="${x + 1}">${x + 1}</option>`
                                    : `<option value="${x + 1}">${x + 1}</option>`
                                )}
                            </select>
                            <button type="button" class="delete-btn" id="">
                            Delete</button>
                        </li>
                        <li class="cart-price">
                            $${item.price}
                        </li>
                    </ul>
                </li>
                `).join('n')
            }
        `;
    }
}

listing.ejs (rewrites old item with new)

<script type="module" defer>
        //add item to cart
        import { getCartItems, setCartItems } from '/scripts/export/localStorage.js';

        const addToCart = (item) => {
            let cartItems = getCartItems();
            const existItem = cartItems.find((x) => x.listing === item.listing);
            if(existItem) {
                cartItems = cartItems.map((x) => x.listing === existItem.listing ? item : x);
            }else{
                cartItems = [...cartItems, item];
            }
            setCartItems(cartItems);
        };

        document.getElementById('add-to-cart-btn').addEventListener('click', () => {
            const name = '<%- listing.name -%>';
            const slug = '<%- listing.slug -%>';
            const image_main = '<%- listing.image_main -%>';
            const price = '<%- listing.price -%>';
            const count_in_stock = '<%- listing.count_in_stock -%>';
            const qty = 1;
            addToCart({
                name,
                slug,
                image_main,
                price,
                count_in_stock,
                qty
            });
        });
    </script>

listing.js (returns all items as undefined)

……..

document.getElementById('add-to-cart-btn').addEventListener('click', () => {
            const name = '<%- listing.name -%>';
            const slug = '<%- listing.slug -%>';
            const image_main = '<%- listing.image_main -%>';
            const price = '<%- listing.price -%>';
            const count_in_stock = '<%- listing.count_in_stock -%>';
            const qty = 1;
            const listing = [name, slug, image_main, price, count_in_stock, qty];
            addToCart({
                listing
            });
        });

Javascript operator showing false output 1===1<3 false

I am trying few operations in java-script please help me to understand the below output or share the reference for reading.

console.log(1===1<3) //output False
console.log('1===1',typeof(1===1),1===1)
console.log('1<2',typeof(1<2),1<2)
console.log(1<2<3)//Outlet ture
console.log(true<3)

As per my understanding in the first output. Should be True but it is giving false.
if first output is false then the last two output will also be false. Please can you explain
Thanks

prevent checkbox if condition doesnt meet

I have a list of checkboxes, inside the input element I have added 2 custom attributes

The checkbox is disabled by default, the idea is thaat if the svcjurisdiction object matches the value of rcpjurisdiction then is enabled, but it isnt working.

$('input[type=checkbox]').each(function() {
     var svcjurisdiction = $(this).attr("data-svcjurisdiction").split(',');
     var rcpjurisdiction = $(this).attr("data-rcpjurisdiction");
  
     console.log(svcjurisdiction)
     if (svcjurisdiction.includes(rcpjurisdiction)) {
       console.log(rcpjurisdiction)
       $(this).attr("disabled",false)
     }

   });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="services" value="13301686-3218159" data-rcpjurisdiction="Guernsey" data-svcjurisdiction="SCPB - LON, Guernsey" type="checkbox" title="Text to show" checked disabled/>

The class ‘HomePage’

error NG6001: The class ‘HomePage’ is listed in the declarations of the NgModule ‘HomePageModule’, but is not a directive, a component, or a pipe. Either remove it from the NgModule’s declarations, or add an appropriate Angular decorator

The error above appear when I did this:

constructor(public modalCtrl:ModalController) {}

async addTask(){
  const modal = await this.modalCtrl.create({
    component: AddNewTaskPage
  })

  return await modal.present()

}

constructor(public modalCtrl:ModalController) {}
ngOnInit(): void {};

async addTask(){
  const modal = await this.modalCtrl.create({
    component: AddNewTaskPage
  })

  return await modal.present()

}

I have expected that AddNewTaskPage be integrated into the project and could be navigated to

React issue with retaining error message when switching between components

I have a React app with multiple containers/section components which have the Field component rendered inside them. These sections get displayed on screen based on the click of the corresponding tab/links (e.g. Section 1, Section 2, etc)
On each section tab/link click, the other MySectionX component is kind of destroyed/removed from DOM as below;

{mySection1 && <MySection1 section={section1} {...props} />}
{mySection2 && <MySection2 section={section2} {...props} />}

In MySection component, I define the field as below and invoke the Field component

let myField = {
    "id": "my-field-1",
    "mandatory": true,
    "visible": true,
    "minFieldLength": 0,
    "items": {},
    "value": "My Field Val 1",
    "event": false,
    "disabled": false,
    "hidden": false,
    "overrideValue": false,
    "readonly": false,
    "fieldLabel": "My Field",
    "newCustomField": false,
    "overrideFieldType": false,
    "editable": true
}

This model is passed to Field as below

<Field key={myField.id} field={myField} handleFieldChange={handleFieldChange} changeFields={changeFieldValues}  />)

My Field component is defined as below

function Field({ classes, field, fieldWidth = '12em', margin = '0 1.5em', handleOnBlur, inputExceptions, validateInputValue, handleFieldChange, inputDisable, showLabel = true, changeFields }) {
    
    const { register } = useFormContext();
    const data = useSelector(state => state.formData.data);
    
    let exceptions = inputExceptions;
    if (field.errorMessages && field.errorMessages.length > 0) {
        exceptions = field.errorMessages;
    }

    let helperText = exceptions && exceptions[0] && exceptions[0].message;
    
    const editableField = () => {
        return (<MyFormField helperText={helperText}
            required={field.mandatory} validationState={exceptions.length > 0 ? 'error' : ''} id={field.id} label={labelText}>
            <Input 
                {...register(field.id)} 
                defaultValue={field.value} 
                value={field.value}
                onChange={handleOnChange} 
                readOnly={field.fieldLength == 0} 
                inputProps={{ maxLength: field.fieldLength, autoComplete: "off", role: 'input' }} 
                disabled={inputDisable} />

        </MyFormField>);
    };

    return editableField;

}

export default withValidation(Field);

I have a HOC as below

export const withValidation = (WrappedComponent) => {
   return function Validator({field, ...otherProps}) {
        const inputValidationRules = [];
        const mandatoryRule = value => value !== '';
        const regexMessage = () => <span>'{field.value}' is not a valid input.</span>;

        if( field.mandatory === true){
            inputValidationRules.push(rule(mandatoryRule, mandatoryMessage)); 
        }
         if(field.regex && field.regex.length > 0) {
            regex = new RegExp(field.regex);
            inputValidationRules.push(rule(regexRule, regexMessage));
        }
        
        const [inputExceptions, validateInputValue] = useValidation(inputValidationRules);
        return (
        <WrappedComponent inputExceptions = {inputExceptions} field = {field} validateInputValue={validateInputValue} {...otherProps}>

        </WrappedComponent>)
    }
}

Now the issue is in retaining error messages below the field while switching between different sections.

Example : Say I am on section 1 and I clear the required field in Section 1. So I get the error below this field. So far, this is good.
But the moment I click on section 2 and come back to section 1, the error message disappears.
So I am wondering how I can get the inputExceptions from the HOC, when switching betwen different sections.

Screenshots inside Shadow DOM are not taken successfully

I am facing issues when taking screenshots on a site which contains a Shadow DOM element.

As it can be seen in below code, I am taking three screenshots. Screenshots are targeting same HTML element, which is contained into a SHADOW root.

const percySnapshot = require('@percy/playwright');
const { chromium, test } = require('@playwright/test');
        
test('Calculator snapshots', async () => {
  const URL = 'https://dev.appgile.com/GlobalCarsTestPage/?country=GB&assetId=IEGR30FIE6WPTA4&assetPrice=59000&model=Grenadier&fsActive=true&loanType=LoanballoonKM&deposit=5900&cookie=true&scripturl=https:%2F%2Fservices.santanderconsumer.com%2Fquoting-tool%2Fscf-plugin.js%3FpluginId%3Da3c00835-e6d7-4565-a311-048af602c448'

  const browser = await chromium.launch();
  const context = await browser.newContext();
  const page = await context.newPage();

  await page.goto(URL, { waitUntil: 'networkidle' });
  await page.locator('text=Test now').click()
  await page.waitForTimeout(7000)

  await percySnapshot(page, 'First snapshot', { scope: 'scf-quoting', widths: [1280] })


  await page.locator('div.scf-products-tabs__link').click()
  await page.waitForTimeout(5000)
  await percySnapshot(page, 'Second snapshot full page', { widths: [1280] })
  await percySnapshot(page, 'Second snapshot for element', { scope: 'scf-quoting', widths: [1280] })
});

First screenshot is taken successfully (except for the black circle being displayed) as you can see in the first screenshot. However, the second and third screenshots do not display expected image. It is quite bizarre, since screenshot are taken to the same element.

I have been researching, and seems taking screenshots of Shadow DOM element is achievable. https://docs.percy.io/docs/shadow-dom

Additionally, I have replicated same code into Cypress, and got exactly same result

First screenshot

Second sceenshot - full page

Second sceenshot - element

Debug logs

[percy:cli:exec] Warning: Missing command separator (--), some command options may not work as expected (0ms)
[percy:config] Config file not found (115ms)
[percy:client] Creating a new build... (49ms)
[percy:core:browser] Launching browser (1142ms)
[percy:core:browser] Browser connected [143875]: HeadlessChrome/96.0.4664.0 (118ms)
[percy:core] Percy has started! (2ms)
[percy:cli:exec] Running "playwright test tests/" (1ms)

Running 1 test using 1 worker
[1/1] [chromium] › example.spec.ts:6:1 › Calculator snapshots
[percy:core:snapshot] --------- (11928ms)
[percy:core:snapshot] Received snapshot: First snapshot (0ms)
[percy:core:snapshot] - url: https://dev.appgile.com/GlobalCarsTestPage/?country=GB&assetId=IEGR30FIE6WPTA4&assetPrice=59000&model=Grenadier&fsActive=true&loanType=LoanballoonKM&deposit=5900&cookie=true&scripturl=https:%2F%2Fservices.santanderconsumer.com%2Fquoting-tool%2Fscf-plugin.js%3FpluginId%3Da3c00835-e6d7-4565-a311-048af602c448 (0ms)
[percy:core:snapshot] - scope: scf-quoting (0ms)
[percy:core:snapshot] - widths: 1280px (0ms)
[percy:core:snapshot] - minHeight: 1024px (0ms)
[percy:core:snapshot] - disableShadowDOM: false (0ms)
[percy:core:snapshot] - discovery.allowedHostnames: dev.appgile.com (0ms)
[percy:core:snapshot] - clientInfo: @percy/playwright/1.0.4 (1ms)
[percy:core:snapshot] - environmentInfo: @percy/playwright/1.0.4 (0ms)
[percy:core:snapshot] - domSnapshot: true (0ms)
[percy:core] Discovering resources: First snapshot (3ms)
[percy:core:page] Page created (6ms)
[percy:core:page] Resize page to 1280x1024 @1x (55ms)
[percy:core:page] Navigate to: https://dev.appgile.com/GlobalCarsTestPage/?country=GB&assetId=IEGR30FIE6WPTA4&assetPrice=59000&model=Grenadier&fsActive=true&loanType=LoanballoonKM&deposit=5900&cookie=true&scripturl=https:%2F%2Fservices.santanderconsumer.com%2Fquoting-tool%2Fscf-plugin.js%3FpluginId%3Da3c00835-e6d7-4565-a311-048af602c448 (3ms)
[percy:core:discovery] Handling request: https://dev.appgile.com/GlobalCarsTestPage/?country=GB&assetId=IEGR30FIE6WPTA4&assetPrice=59000&model=Grenadier&fsActive=true&loanType=LoanballoonKM&deposit=5900&cookie=true&scripturl=https:%2F%2Fservices.santanderconsumer.com%2Fquoting-tool%2Fscf-plugin.js%3FpluginId%3Da3c00835-e6d7-4565-a311-048af602c448 (37ms)
[percy:core:discovery] - Serving root resource (0ms)
[percy:core:discovery] Handling request: https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap (29ms)
[percy:core:discovery] Handling request: https://fonts.googleapis.com/icon?family=Material+Icons (1ms)
[percy:core:discovery] Handling request: https://dev.appgile.com/GlobalCarsTestPage/styles.css (0ms)
[percy:core:discovery] Handling request: https://dev.appgile.com/GlobalCarsTestPage/assets/img/scf-logo.svg (7ms)
[percy:core:discovery] Handling request: https://www.googletagmanager.com/ns.html?id=GTM-WW8K456 (6ms)
[percy:core:discovery] Handling request: https://www.googletagmanager.com/ns.html?id=GTM-5M4P447 (2ms)
[percy:core:discovery] Handling request: https://dev.appgile.com/__serialized__/_ye9xmjg6g.css (24ms)
[percy:core:discovery] - Resource cache hit (0ms)
[percy:core:discovery] Processing resource: https://www.googletagmanager.com/ns.html?id=GTM-WW8K456 (183ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Handling request: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderText-Regular.woff (266ms)
[percy:core:discovery] Handling request: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderHeadline-Regular.woff (847ms)
[percy:core:discovery] Handling request: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderText-Bold.woff (1ms)
[percy:core:discovery] Processing resource: https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap (0ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://fonts.googleapis.com/icon?family=Material+Icons (1ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://dev.appgile.com/GlobalCarsTestPage/assets/img/scf-logo.svg (6ms)
[percy:core:discovery] Processing resource: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderText-Regular.woff (6ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://dev.appgile.com/GlobalCarsTestPage/styles.css (5ms)
[percy:core:discovery] Handling request: https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2 (437ms)
[percy:core:discovery] Handling request: https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmEU9fBBc4.woff2 (1ms)
[percy:core:discovery] - sha: 571028ba8efcf458391da7b28fdecc04b22fcc0c962907822d7b82db0a631889 (8ms)
[percy:core:discovery] - mimetype: image/svg+xml (0ms)
[percy:core:discovery] - sha: 829b926688e708555282e7f567bcfcff69f28dccfde9a8da44a7ee22e10be305 (8ms)
[percy:core:discovery] - mimetype: text/css (0ms)
[percy:core:discovery] Processing resource: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderHeadline-Regular.woff (9ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderText-Bold.woff (3ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://www.googletagmanager.com/ns.html?id=GTM-5M4P447 (42ms)
[percy:core:discovery] - Skipping remote resource (1ms)
[percy:core:discovery] Processing resource: https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2 (79ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmEU9fBBc4.woff2 (31ms)
[percy:core:discovery] - Skipping remote resource (1ms)
[percy:core:page] Page navigated (5ms)
[percy:core:discovery] Wait for 100ms idle (3ms)
[percy:core] Snapshot taken: First snapshot (102ms)
[percy:client] Creating snapshot: First snapshot... (1ms)
[percy:core:page] Page closed (6ms)
[percy:client] Uploading resources for 26148950... (316ms)
[percy:client] Uploading resource: /percy.1679668197054.log... (1ms)
[percy:client] Uploading resource: https://dev.appgile.com/GlobalCarsTestPage/?country=GB&assetId=IEGR30FIE6WPTA4&assetPrice=59000&model=Grenadier&fsActive=true&loanType=LoanballoonKM&deposit=5900&cookie=true&scripturl=https:%2F%2Fservices.santanderconsumer.com%2Fquoting-tool%2Fscf-plugin.js%3FpluginId%3Da3c00835-e6d7-4565-a311-048af602c448... (1ms)
[percy:client] Finalizing snapshot 1457349132... (1408ms)
[percy:core:snapshot] --------- (3476ms)
[percy:core:snapshot] Received snapshot: Second snapshot full page (0ms)
[percy:core:snapshot] - url: https://dev.appgile.com/GlobalCarsTestPage/?country=GB&assetId=IEGR30FIE6WPTA4&assetPrice=59000&model=Grenadier&fsActive=true&loanType=LoanballoonKM&deposit=5900&cookie=true&scripturl=https:%2F%2Fservices.santanderconsumer.com%2Fquoting-tool%2Fscf-plugin.js%3FpluginId%3Da3c00835-e6d7-4565-a311-048af602c448 (1ms)
[percy:core:snapshot] - widths: 1280px (0ms)
[percy:core:snapshot] - minHeight: 1024px (0ms)
[percy:core:snapshot] - disableShadowDOM: false (0ms)
[percy:core:snapshot] - discovery.allowedHostnames: dev.appgile.com (0ms)
[percy:core:snapshot] - clientInfo: @percy/playwright/1.0.4 (0ms)
[percy:core:snapshot] - environmentInfo: @percy/playwright/1.0.4 (0ms)
[percy:core:snapshot] - domSnapshot: true (0ms)
[percy:core] Discovering resources: Second snapshot full page (1ms)
[percy:core:page] Page created (3ms)
[percy:core:page] Resize page to 1280x1024 @1x (42ms)
[percy:core:page] Navigate to: https://dev.appgile.com/GlobalCarsTestPage/?country=GB&assetId=IEGR30FIE6WPTA4&assetPrice=59000&model=Grenadier&fsActive=true&loanType=LoanballoonKM&deposit=5900&cookie=true&scripturl=https:%2F%2Fservices.santanderconsumer.com%2Fquoting-tool%2Fscf-plugin.js%3FpluginId%3Da3c00835-e6d7-4565-a311-048af602c448 (4ms)
[percy:core:discovery] Handling request: https://dev.appgile.com/GlobalCarsTestPage/?country=GB&assetId=IEGR30FIE6WPTA4&assetPrice=59000&model=Grenadier&fsActive=true&loanType=LoanballoonKM&deposit=5900&cookie=true&scripturl=https:%2F%2Fservices.santanderconsumer.com%2Fquoting-tool%2Fscf-plugin.js%3FpluginId%3Da3c00835-e6d7-4565-a311-048af602c448 (4ms)
[percy:core:discovery] - Serving root resource (1ms)
[percy:core:discovery] Handling request: https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap (32ms)
[percy:core:discovery] Handling request: https://fonts.googleapis.com/icon?family=Material+Icons (1ms)
[percy:core:discovery] Handling request: https://dev.appgile.com/GlobalCarsTestPage/styles.css (2ms)
[percy:core:discovery] - Resource cache hit (0ms)
[percy:core:discovery] Handling request: https://dev.appgile.com/GlobalCarsTestPage/assets/img/scf-logo.svg (9ms)
[percy:core:discovery] - Resource cache hit (2ms)
[percy:core:discovery] Handling request: https://www.googletagmanager.com/ns.html?id=GTM-WW8K456 (3ms)
[percy:core:discovery] Handling request: https://www.googletagmanager.com/ns.html?id=GTM-5M4P447 (7ms)
[percy:core:discovery] Handling request: https://dev.appgile.com/__serialized__/_y6bs6lde8.css (24ms)
[percy:core:discovery] - Resource cache hit (1ms)
[percy:core:discovery] Processing resource: https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap (25ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://fonts.googleapis.com/icon?family=Material+Icons (1ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Handling request: https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2 (655ms)
[percy:core:discovery] Handling request: https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmEU9fBBc4.woff2 (0ms)
[percy:core:discovery] Handling request: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderText-Regular.woff (1ms)
[percy:core:discovery] Handling request: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderHeadline-Bold.woff (0ms)
[percy:core:discovery] Handling request: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderText-Bold.woff (0ms)
[percy:core:discovery] Processing resource: https://www.googletagmanager.com/ns.html?id=GTM-WW8K456 (15ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://www.googletagmanager.com/ns.html?id=GTM-5M4P447 (0ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderText-Regular.woff (111ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderText-Bold.woff (4ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderHeadline-Bold.woff (0ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2 (4ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmEU9fBBc4.woff2 (43ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:page] Page navigated (10ms)
[percy:core:discovery] Wait for 100ms idle (1ms)
[percy:core] Snapshot taken: Second snapshot full page (102ms)
[percy:client] Creating snapshot: Second snapshot full page... (0ms)
[percy:core:page] Page closed (5ms)
[percy:core:snapshot] --------- (96ms)
[percy:core:snapshot] Received snapshot: Second snapshot for element (1ms)
[percy:core:snapshot] - url: https://dev.appgile.com/GlobalCarsTestPage/?country=GB&assetId=IEGR30FIE6WPTA4&assetPrice=59000&model=Grenadier&fsActive=true&loanType=LoanballoonKM&deposit=5900&cookie=true&scripturl=https:%2F%2Fservices.santanderconsumer.com%2Fquoting-tool%2Fscf-plugin.js%3FpluginId%3Da3c00835-e6d7-4565-a311-048af602c448 (0ms)
[percy:core:snapshot] - scope: scf-quoting (0ms)
[percy:core:snapshot] - widths: 1280px (0ms)
[percy:core:snapshot] - minHeight: 1024px (1ms)
[percy:core:snapshot] - disableShadowDOM: false (0ms)
[percy:core:snapshot] - discovery.allowedHostnames: dev.appgile.com (0ms)
[percy:core:snapshot] - clientInfo: @percy/playwright/1.0.4 (0ms)
[percy:core:snapshot] - environmentInfo: @percy/playwright/1.0.4 (0ms)
[percy:core:snapshot] - domSnapshot: true (1ms)
[percy:core] Discovering resources: Second snapshot for element (2ms)
[percy:core:page] Page created (6ms)
[percy:core:page] Resize page to 1280x1024 @1x (47ms)
[percy:core:page] Navigate to: https://dev.appgile.com/GlobalCarsTestPage/?country=GB&assetId=IEGR30FIE6WPTA4&assetPrice=59000&model=Grenadier&fsActive=true&loanType=LoanballoonKM&deposit=5900&cookie=true&scripturl=https:%2F%2Fservices.santanderconsumer.com%2Fquoting-tool%2Fscf-plugin.js%3FpluginId%3Da3c00835-e6d7-4565-a311-048af602c448 (4ms)
[percy:core:discovery] Handling request: https://dev.appgile.com/GlobalCarsTestPage/?country=GB&assetId=IEGR30FIE6WPTA4&assetPrice=59000&model=Grenadier&fsActive=true&loanType=LoanballoonKM&deposit=5900&cookie=true&scripturl=https:%2F%2Fservices.santanderconsumer.com%2Fquoting-tool%2Fscf-plugin.js%3FpluginId%3Da3c00835-e6d7-4565-a311-048af602c448 (3ms)
[percy:core:discovery] - Serving root resource (0ms)
[percy:core:discovery] Handling request: https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap (38ms)
[percy:core:discovery] Handling request: https://fonts.googleapis.com/icon?family=Material+Icons (0ms)
[percy:core:discovery] Handling request: https://dev.appgile.com/GlobalCarsTestPage/styles.css (1ms)
[percy:core:discovery] - Resource cache hit (0ms)
[percy:core:discovery] Handling request: https://dev.appgile.com/GlobalCarsTestPage/assets/img/scf-logo.svg (10ms)
[percy:core:discovery] - Resource cache hit (0ms)
[percy:core:discovery] Handling request: https://www.googletagmanager.com/ns.html?id=GTM-WW8K456 (12ms)
[percy:core:discovery] Handling request: https://www.googletagmanager.com/ns.html?id=GTM-5M4P447 (2ms)
[percy:core:discovery] Handling request: https://dev.appgile.com/__serialized__/_bt7reynsc.css (25ms)
[percy:core:discovery] - Resource cache hit (1ms)
[percy:core:discovery] Processing resource: https://fonts.googleapis.com/icon?family=Material+Icons (19ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap (1ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:client] Uploading resources for 26148950... (51ms)
[percy:client] Uploading resource: https://dev.appgile.com/GlobalCarsTestPage/?country=GB&assetId=IEGR30FIE6WPTA4&assetPrice=59000&model=Grenadier&fsActive=true&loanType=LoanballoonKM&deposit=5900&cookie=true&scripturl=https:%2F%2Fservices.santanderconsumer.com%2Fquoting-tool%2Fscf-plugin.js%3FpluginId%3Da3c00835-e6d7-4565-a311-048af602c448... (0ms)
[percy:client] Uploading resource: /percy.1679668203373.log... (1ms)
[percy:core:discovery] Handling request: https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2 (643ms)
[percy:core:discovery] Handling request: https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmEU9fBBc4.woff2 (1ms)
[percy:core:discovery] Handling request: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderText-Regular.woff (0ms)
[percy:core:discovery] Handling request: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderHeadline-Bold.woff (1ms)
[percy:core:discovery] Handling request: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderText-Bold.woff (0ms)
[percy:core:discovery] Processing resource: https://www.googletagmanager.com/ns.html?id=GTM-WW8K456 (16ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://www.googletagmanager.com/ns.html?id=GTM-5M4P447 (1ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2 (32ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://fonts.gstatic.com/s/roboto/v30/KFOlCnqEu92Fr1MmEU9fBBc4.woff2 (5ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:client] Finalizing snapshot 1457349184... (26ms)
[percy:core:discovery] Processing resource: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderText-Regular.woff (15ms)
[percy:core:discovery] - Skipping remote resource (0ms)
[percy:core:discovery] Processing resource: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderText-Bold.woff (6ms)
[percy:core:discovery] - Skipping remote resource (2ms)
[percy:core:discovery] Processing resource: https://services.santanderconsumer.com/quoting-tool/UI/assets/fonts/SantanderHeadline-Bold.woff (52ms)
[percy:core:discovery] - Skipping remote resource (1ms)
[percy:core:page] Page navigated (9ms)
[percy:core:discovery] Wait for 100ms idle (1ms)
[percy:core] Snapshot taken: Second snapshot for element (100ms)
[percy:client] Creating snapshot: Second snapshot for element... (1ms)
  1 passed (21.4s)

To open last HTML report run:

  npx playwright show-report

[percy:client] Uploading resources for 26148950... (320ms)
[percy:client] Uploading resource: /percy.1679668204611.log... (1ms)
[percy:client] Uploading resource: https://dev.appgile.com/GlobalCarsTestPage/?country=GB&assetId=IEGR30FIE6WPTA4&assetPrice=59000&model=Grenadier&fsActive=true&loanType=LoanballoonKM&deposit=5900&cookie=true&scripturl=https:%2F%2Fservices.santanderconsumer.com%2Fquoting-tool%2Fscf-plugin.js%3FpluginId%3Da3c00835-e6d7-4565-a311-048af602c448... (0ms)
[percy:client] Finalizing snapshot 1457349208... (754ms)
[percy:core:browser] Closing browser (286ms)
[percy:core:browser] Browser closed (51ms)
[percy:client] Finalizing build 26148950... (0ms)
[percy:core] Finalized build #34: https://percy.io/215ec123/Global-Simulation-Tool---Dev-v2/builds/26148950 (250ms)

Refresh same tabs in javascript/react instead of opening new tab on browser window

There is a requirement on our tool wherein when a task is fetched, autopop new tabs like google search, amazon search and amazon product detail page(total 3 tabs) should automatically open in new tabs.

The backend API sends an array like this to frontend for the urls to autopopup in new tab when the task is fetched. Example array is :

"autoPopUpTabAttributesList": ["https://www.google.it/search?q=cover iphone 11 mini con sora i disegni", "https://www.amazon.it/s?k=cover iphone 11 mini con sora i disegni", "https://www.amazon.it/dp/B0BTD7BNR5"]

Currently I am using this code to automatically open the new tabs when task is fetched:

    /**
    * Function used to auto open the url in new tab of same window.
    * @param {*} url 
    */
    const openInNewTab = (url) => {
        const newWindow = window.open(url, '_blank', 'noopener,noreferrer')
        if (newWindow) newWindow.opener = null
      }


...
...

return (
...
...
{props.autoPopup && popUpTabUrlArray.forEach((url,ind) => {
                    if(url && common.isValidHttpUrl(url))
                        openInNewTab(url);
                 })}
)

CURRENT BEHAVIOUR: What happens here is whenever the first task is fetched, the 3 new tabs open up as expected. Now, when next task is fetched- the new array with 3 urls come from backend and 3 new tabs open up again(now there are 6 tabs in total:3 from first and next 3 from second task). Same behaviour for 3rd, 4th , 5th task etc where new tabs add up.

EXPECTED BEHAVIOUR: However, what customer is expecting is: when first task is fetched- 3 new tabs will pop up but when second task is fetched: instead of opening 3 new tabs again – the first 3 tabs(from task 1) should be automatically refreshed with the new tabs(from task 2).
Why they need this:

  • without this: multiple tabs will be left open on browser and time has to be spent closing it which they don’t want to.
  • there might be confusion when working on the task wherein the customer sees the pop up tab of previous task tabs and saves response for second task.

Hence, can you help me with refreshing the same 3 tabs again instead of the current behaviour of opening 3 new tabs again?
Or the other approach i can think of is close the first 3 tabs when second task is fetched and open the 3 new tabs?
Either way i did not find how to achieve this. Can experts help me? Thanks.

How to decrypt large files (+ 1 GB) with AES-CBC chunk by chunk in javascript (Web)?

We are trying to build a stream decrypt of large files in Javascript (browsers). As stream decryption isn’t natively supported by crypto.Subtle we are doing that chunk by chunk. Which should be possible by providing the previous chunk as the iv for the current chunk.

But it seems Crypto.subtle is always expecting a padding at the end of the chunk. (Confirmed here: What padding does window.crypto.subtle.encrypt use for AES-CBC). Which makes an implementation feel strange to say the least.

Does anyone have any examples or ideas how to do this in javascript, while still using native api’s?

We have come up with this:

const chunkSize = 16;
let index = 0;
const chunks = [];
let prevChunk = null;
do {
    const chunk = ciphertext.slice(index, index + chunkSize);
    
    // Encrypt padding with the chunk as iv
    const paddingCypher = await crypto.subtle.encrypt({ name: 'AES-CBC', iv: chunk }, key, padding);
    const encryptedPadding = (new Uint8Array(paddingCypher)).slice(0, 16);

    const decrypted = await crypto.subtle.decrypt({ name: 'AES-CBC', iv: prevChunk || subtleIv}, subtleKey, mergeByteArrays([chunk, encryptedPadding]));
    chunks.push(new Uint8Array(decrypted));

    prevChunk = chunk;
    index += chunkSize;
} while (index < length - chunkSize);

// Different for last chunk as that already has the padding
const lastChunk = await decrypt(
    prevChunk || subtleIv,
    subtleKey,
    ciphertext.slice(index, index + chunkSize)
);
chunks.push(new Uint8Array(lastChunk));

var mergedChunks = mergeByteArrays(chunks);

// Decode and output
var fullyDecrypted = String.fromCharCode.apply(null, mergedChunks as any);
console.log(fullyDecrypted);```

what is the correct ways to write routes in reactJs?

There are some routes presents in my application. I want to render the feed details in the same parent route rather than opening a different/rendering new url. Catch is Search page is also there which i also want to render in the parent route, but the route is not working as i expected it to be.

What i tried: Used react outlook hook to render in the parent element, which is working. But the search routes is not rendering as i want it to be only the link is getting changed.

What should i do to solve this.

I have made a design prototype of my application also. Upon requests i would include it.

Webpack errors after migrating to Next 13

After upgrading Next to version 13 our application does not build it looks like webpack have problem with imports and exports and presumably typescript

../../libs/queries/src/lib/groq/searchFaq.ts
Module parse failed: Unexpected token (1:37)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> export const searchFaqQuery = (market: string, language: string, searchTerm: string) => {
|   const searchTermArray = searchTerm.split(' ').map((word) => word + '*');
|   const queryFilters = `market == '${market}' && language == '${language}' && _type == 'faq' && !(_id in path("drafts.**"))`;

Import trace for requested module:
../../libs/queries/src/lib/groq/searchFaq.ts
../../libs/queries/src/index.ts

../../libs/utils/src/lib/components/atoms/BulletListWrapper/BulletListWrapper.tsx
Module parse failed: Unexpected token (4:5)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| import * as Styled from './BulletListWrapper.style';
| 
> type TBulletListWrapper = {
|   children: React.ReactNode;
| };

Import trace for requested module:
../../libs/utils/src/lib/components/atoms/BulletListWrapper/BulletListWrapper.tsx
../../libs/utils/src/lib/components/atoms/index.ts
../../libs/utils/src/lib/components/index.ts
../../libs/utils/src/index.ts

The list of errors is longer but are very similiar to those above. My next.config.js looks this way:

module.exports = {
  env: {
    NEXT_PUBLIC_TOKEN: process.env.NEXT_PUBLIC_SANITY_TOKEN,
    NEXT_PUBLIC_PREVIEW_SECRET: process.env.NEXT_PUBLIC_SANITY_PREVIEW_SECRET,
    NEXT_PUBLIC_PROJECT_ID: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
  },
  i18n: {
    defaultLocale: 'et',
    locales: ['et', 'ru'],
  },
  basePath: '/ee',
  reactStrictMode: true,
  images: {
    domains: ['cdn.images.io'],
    formats: ['image/webp'],
  },
  experimental: {
    forceSwcTransforms: true,
  },
  swcMinify: true,
  webpack(config) {
    config.resolve.fallback = { fs: false, path: false };
    config.module.rules.push({
      test: /.svg$/,
      issuer: {
        and: [/.(js|ts)x?$/],
      },
      use: ['@svgr/webpack'],
    });

    return config;
  },
};

Would you please point me in the right direction? We have a monorepo with NX and I after upgrade everything works without a problem in development, but when it came to bulding the app there seems to be a problem. Thanks.