Let Selenium driver wait till all GraphQL requests are finished

I’m writing some Selenium tests (in c#) for React app.

I need to let (Chrome)Driver wait until all GraphQL requests are finished. I have method that waits till all jQuery requests are finished:

WebDriverWait.Until(d => (bool)((IJavaScriptExecutor)Driver).ExecuteScript("return window.jQuery != undefined && jQuery.active == 0"))

but I need to rewrite this query for GraphQL requests.

Thank you in advance.

How to Persist Dynamically Added Conditions in a Custom Node in Node-RED?

I’m working on a custom Node-RED node that allows users to define dynamic conditions based on two properties: name and age. Users can dynamically add conditions using a button, where each condition consists of a property, operator, and parameter. By default, I want to provide two conditions (one for name and one for age), and users can modify the operator and add the parameter.

The problem I’m facing is that dynamically added conditions do not persist after the user clicks “Done” in the node’s dialog. When I deploy the flow and reopen the node, the previously set conditions are lost, even though I attempt to save them in the oneditsave function.

Here is a simplified version of my code:

RED.nodes.registerType('condition-task', {
    category: 'function',
    color: '#a6bbcf',
    defaults: {
        name: { value: "" },
        conditions: [] // Empty array for dynamic conditions
    },
    inputs: 1,
    outputs: 3,
    icon: "file.svg",
    label: function () {
        return this.name || "condition-task";
    },
    oneditprepare: function () {
        const conditionList = $("#node-input-conditions");
        conditionList.empty(); // Clear any existing conditions

        // Populate the conditions from the saved configuration (if any)
        this.conditions.forEach(condition => {
            conditionList.append(createConditionRow(condition));
        });

        // Add new condition row
        $("#add-condition").on("click", function () {
            conditionList.append(createConditionRow());
        });
    },
    oneditsave: function () {
        const conditions = [];
        $("#node-input-conditions li").each(function () {
            const property = $(this).find(".condition-property").val();
            const operator = $(this).find(".condition-operator").val();
            const parameter = $(this).find(".condition-parameter").val();
            conditions.push({ property, operator, parameter });
        });
        this.conditions = conditions; // Save to node config
    }
});

HTML Template:

<script type="text/html" data-template-name="condition-task">
    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
        <input type="text" id="node-input-name" placeholder="Name">
    </div>
    <div class="form-row">
        <label><i class="fa fa-list"></i> Conditions</label>
        <ol id="node-input-conditions" style="list-style: none; padding: 0;">
            <li style="margin-bottom: 5px;">
                <select class="condition-property" style="width: 30%;">
                    <option value="name" selected>name</option>
                    <option value="age">age</option>
                </select>
                <select class="condition-operator" style="width: 20%;">
                    <option value="==" selected>==</option>
                    <option value="!=">!=</option>
                </select>
                <input type="text" class="condition-parameter" placeholder="Parameter" style="width: 30%;" value="">
            </li>
        </ol>
        <button id="add-condition" class="red-ui-button red-ui-button-small">
            <i class="fa fa-plus"></i> Add Condition
        </button>
    </div>
</script>

Problem:
After dynamically adding conditions and setting values for the property, operator, and parameter, the conditions are not saved when I click “Done” in the node’s edit dialog.
When I deploy the flow and reopen the node, all previously set conditions are lost. This is occurring even though I attempt to save the conditions using the oneditsave function.
The goal is to save all dynamically added conditions (property, operator, and parameter) and ensure they persist after deployment and reopening of the node.
What I’ve Tried:
I used the oneditsave function to gather the conditions and save them to the node’s configuration, but it doesn’t persist the changes.
I’ve tried populating the conditions dynamically when the node’s edit dialog is opened, but the previously added conditions do not appear after deployment.
Expected Behavior:
The dynamically added conditions (property, operator, and parameter) should be saved when the user clicks “Done” in the node’s edit dialog and should persist after deployment and when the node is reopened.

How to make the default image description visible in WordPress?

I have an image gallery on a WordPress site created with the Photo Gallery by 10Web plugin. When we click on an image, a LIGHT-BOX opens, I need the description of the images to be displayed by default, always. However, they are only displayed when we click on a button, by default, this information is hidden: button:

<i title="Mostrar info" class="bwg-icon-info-circle bwg_ctrl_btn bwg_info"></i>

This is when we have already touched the INFORMATION button:

 <i title="Anterior información" class="bwg-icon-info-circle bwg_ctrl_btn bwg_info"></i>

The complete html element that is displayed when the button is clicked is as follows:

Abuelo Nicolas Fernandez
Imagen de Abuelo Nicolas Fernandez

I’ve created a function to force the behavior, but it doesn’t work. I’ve tried to do it with css, but it doesn’t work.

How can I make the description show by default?

/* Force visibility of information in the lightbox */
.bwg_lightbox .bwg_image_info_container1 {
    display: table-cell !important;
    visibility: visible !important;
    opacity: 1 !important;
}

/* Force visibility of inner content *
.bwg_lightbox .mCSB_container {
    visibility: visible !important;
    opacity: 1 !important;
}

/* Ensure synchronization of the info button */
.bwg_lightbox .bwg_info {
    display: inline-block !important;
}

I have also tried using JS in various ways, even with the help of an expert:

function forzar_mostrar_info_con_css_js() {
    ?>
    <script>
        document.addEventListener("DOMContentLoaded", function () {
           // Function to force visibility
            function forzarVisibilidad() {
                const lightbox = document.querySelector(".bwg_lightbox");
                if (lightbox && lightbox.style.display !== "none") {
                    // Information container
                    const infoContainer = lightbox.querySelector(".bwg_image_info_container1");
                    if (infoContainer) {
                        infoContainer.style.setProperty("display", "table-cell", "important");
                        infoContainer.style.setProperty("visibility", "visible", "important");
                        infoContainer.style.setProperty("opacity", "1", "important");
                    }

                    // Info button
                    const infoButton = lightbox.querySelector(".bwg_info");
                    if (infoButton) {
                        infoButton.classList.add("active");
                    }
                }
            }

            // Watch for changes in the DOM to detect the lightbox opening
            const observer = new MutationObserver(() => forzarVisibilidad());

            observer.observe(document.body, {
                attributes: true,
                childList: true,
                subtree: true,
            });

            // Also run on clicks inside the lightbox
            document.body.addEventListener("click", function (event) {
                if (event.target.closest(".bwg_lightbox")) {
                    setTimeout(forzarVisibilidad, 100);
                }
            });
        });
    </script>
    <?php
}
add_action('wp_footer', 'forzar_mostrar_info_con_css_js', 100);

//////////////////////

More proven options:

function forzar_mostrar_info_contenedor() {
    ?>
    <script>
        document.addEventListener("DOMContentLoaded", function () {
            function forzarInformacionActiva() {
                // Identify the parent container and its children
                const lightbox = document.querySelector(".bwg_lightbox");
                if (lightbox && lightbox.style.display !== "none") {
                    const infoContainer = lightbox.querySelector("#mCSB_1_container");
                    const parentContainer = lightbox.querySelector("#mCSB_1");

                    if (infoContainer && parentContainer) {
                        // Remove classes that hide information
                        infoContainer.classList.remove("mCS_y_hidden", "mCS_no_scrollbar_y");
                        parentContainer.classList.remove("mCS_y_hidden", "mCS_no_scrollbar_y");

                        // Force styles to ensure visibility
                        parentContainer.style.setProperty("max-height", "none", "important");
                        parentContainer.style.setProperty("visibility", "visible", "important");
                        parentContainer.style.setProperty("opacity", "1", "important");

                        infoContainer.style.setProperty("position", "relative", "important");
                        infoContainer.style.setProperty("top", "0", "important");
                        infoContainer.style.setProperty("left", "0", "important");
                        infoContainer.style.setProperty("visibility", "visible", "important");
                    }
                }
            }

          // Observer to detect changes in the DOM
            const observer = new MutationObserver(() => forzarInformacionActiva());
            observer.observe(document.body, {
                attributes: true,
                childList: true,
                subtree: true,
            });

            // Also run on clicks related to the lightbox
            document.body.addEventListener("click", function (event) {
                if (event.target.closest(".bwg_lightbox")) {
                    setTimeout(forzarInformacionActiva, 100);
                }
            });
        });
    </script>
    <?php
}
add_action('wp_footer', 'forzar_mostrar_info_contenedor', 100);

Type ‘Props’ does not satisfy the constraint ‘PageProps’ Next.js 15.1.3

Can someone help me about this error. I cant find any solutions about it.

.next/types/app/admin/editmodel/[markaid]/page.ts:34:29

Type error: Type ‘{ params: ModelProps; }’ does not satisfy the constraint ‘PageProps’.

Types of property ‘params’ are incompatible.

Type ‘ModelProps’ is missing the following properties from type ‘Promise’: then, catch, finally, [Symbol.toStringTag]

32 |

33 | // Check the prop type of the entry function

34 | checkFields<Diff<PageProps, FirstArg<TEntry[‘default’]>, ‘default’>>()

| ^

35 |

36 | // Check the arguments and return type of the generateMetadata function

37 | if (‘generateMetadata’ in entry) {

Static worker exited with code: 1 and signal: null

I am trying to build and deploy my project and i get this error cant solve it.

How do I remove unsafe-inline from Content Security Policy and use server-send data to generate html elements, triggered by user interaction?

I have a web interface, that use JavaScript function to create html elements using data from data-* attribute created by web-server. This function will be triggered by onchange event of a checkbox.

java-script function and the part for add event listener are both inside an external static java-script. Using defer add_event_listener will be triggered after the page has finished loading.

My question is, how do I change the script, so that Content Security Policy with script-src: ‘self’; works, without ‘unsafe-inline’ to avoid XSS attacks?

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; style-src 'self'">
</head>
<body>
<script  src="./script.js" defer></script>
<div id="data-display">hi</div>
<label for="radio-1">radio-1
    <input class="radio-1" id="radio-1" name="radio" value="1" type="radio">
</label>
<label for="radio-2">radio-2
    <input class="radio-1" id="radio-2" name="radio" value="2" type="radio">
</label>
</body>
</html>

change meta tag content to content=”script-src ‘unsafe-inline’ ‘self’; style-src ‘self'” to avoid error:
“The page’s settings blocked an event handler (script-src-attr) from being executed because it violates the following directive: “script-src ‘self'”

function changeData(data) {
    var data_display = document.getElementById('data-display');
    data_display.innerHTML = '';
    p = document.createElement("p");
    p.innerText = data;
    data_display.appendChild(p);
}
document.querySelectorAll('.radio-1').forEach( (element) => {
    element.setAttribute("onchange", "changeData('hi radio')");
});

I am thinking about generate all those html elements server-side, and make them hidden.
Only use JavaScript to make them visible.
The problem is: I will have 20 to 30 different but similar divs to display/hide, and that is wasteful.
I hope there are more elegant solutions out there.

Cannot access object property inside of promise, but can access whole object

For context, I am using Vue3, and the following code is inside the onMounted function of a component:

SettingsPage.vue:

    onMounted(async () => {

    // Fetch available locales from API
    availableLocales.value = await api.locale.getLocales().then((response => response.locales))

    // Fetch user settings from API
    var settings = await api.user.getUserSettings().then(response => {

    console.log(response.userSettings) 
    // Correctly displays the object, including all the values of all properties correctly
    //{mainLocale: ?, darkMode: ? etc...}
    console.log(response.userSettings.mainLocale)
    // Displays undefined

The api call is in another file:

api.ts

    getUserSettings: async (): Promise<UserSettingsResponse> => {
      return await axiosService.get(`/api/user/settings/get`).then((response) => response.data);
    },

The problem is displayed in the comments, I can successfully print the whole object, getting all the relevant information correctly, but I am not able to fetch a single property from within the object, as it returns “undefined”.

I have looked around and tried various “hacks”, such as JSON.parse(JSON.stringify(response.userSettings)), and nothing has worked.

How to include ALL parameters in the URL captured in Javascript, to add full URL to a pre-populated email

I can successfully pre-populate an email from a button click with the first part of the page URL, and the first parameter in the URL, but it’s cutting off after that. I have multiple parameters in the URL. How do I capture them all and put the full URL in the link in the email?

So for the url e.g. https://website.com/folder?param1=one&param2=two

Current code:

<div class="button">
  <a href="mailto:?subject=Email title&body=Here’s a link: &nbsp; [sub]" data-message="" 

onclick=”this.href = this.href.replace(‘[sub]’,window.location)”>Email me a link to this page

This is populating the email link part with https://website.com/folder?param1=one only. &param2=two is missing.

I’ve also tried with

<div class="button">
  <a href="mailto:?subject=Email title&body=Here’s a link: &nbsp;" data-message="" 

onclick=”this.href += window.location.href;”>Email me a link to this page

Which has the same result.

I have a feeling it’s to do with needing to use URLSearchParams and specify the parameter names, but I don’t know how to write this into the existing code. I read MDN but I’m a beginner so need help.

Thanks in advance.

USER ID NOT FOUND

I’m trying to work with product adding but there’s a problem no matter how I set the withCredentials to true. Still the backend responds with an error ‘User not found’. It’s as if it can’t detect the token that was stored inside the cookie

This is my addProduct function in my productController:

export const addProduct = async (req, res) => {
  try {
    const { userId, name, description, price, category, subCategory, sizes, bestseller } = req.body;

    const image1 = req.files.image1 && req.files.image1[0];
    const image2 = req.files.image2 && req.files.image2[0];
    const image3 = req.files.image3 && req.files.image3[0];
    const image4 = req.files.image4 && req.files.image4[0];

    const images = [image1, image2, image3, image4].filter(item => item !== undefined);

    let imagesUrl = await Promise.all(
      images.map(async item => {
        let result = await cloudinary.uploader.upload(item.path, {
          resource_type: "image",
        });
        return result.secure_url;
      })
    );

    const productData = {
      name,
      description,
      category,
      price: Number(price),
      subCategory,
      bestseller: bestseller === "true",
      sizes: JSON.parse(sizes),
      image: imagesUrl,
      date: Date.now(),
    };

    // Add product to seller's products array
    const seller = await sellerModel.findById(userId);
    if (!seller) {
      return res.json({ success: false, msg: "Seller not found" });
    }
    console.log(userId)
    seller.products.push(productData);
    await seller.save();

    res.json({ success: true, msg: "Product Added" });
  } catch (err) {
    console.log(err);
    res.json({ success: false, msg: err.message });
  }
};  

Add.jsx code:

import { useState } from 'react'
import { assets } from '../assets/seller_assets/assets'
import axios from 'axios'
import { backendUrl } from '../App'
import { toast } from 'react-toastify'


const Add = () => {
 
  const [image1, setImage1] = useState(false)
  const [image2, setImage2] = useState(false)
  const [image3, setImage3] = useState(false)
  const [image4, setImage4] = useState(false)

  const [name, setName] = useState('');
  const [description, setDescription] = useState("")
  const [price, setPrice] = useState("")
  const [category, setCategory] = useState("Men");
  const [subCategory, setSubCategory] = useState("Topwear");
  const [bestseller, setBestSeller] = useState(false);
  const [sizes, setSizes] = useState([])

  const onSubmitHandler = async (e) => {
    e.preventDefault();
    try {
     
      const formData = new FormData();
      formData.append("name", name);
      formData.append("description", description)
      formData.append("price", price)
      formData.append("category", category)
      formData.append("subCategory", subCategory)
      formData.append("bestseller", bestseller)
      formData.append("sizes", JSON.stringify(sizes))

      image1  && formData.append("image1", image1);
      image2  && formData.append("image2", image2);
      image3  && formData.append("image3", image3);
      image4  && formData.append("image4", image4);

      const response = await axios.post(backendUrl+'/api/seller/add',formData,{headers: {"Content-Type": "multipart/form-data"}, withCredentials:true})

      if(response.data.success) {
        toast.success(response.data.msg);
        setName('')
        setDescription('')
        setPrice('')
        setImage1(false)
        setImage2(false)
        setImage3(false)
        setImage4(false)
        setBestSeller(false)
      }else {
        toast.error(response.data.msg)
      }
     
      
    } catch (error) {
      console.log(error.message)
      toast.error(error.message)
      
    }
  }

  return (
    <form onSubmit={onSubmitHandler} className='flex flex-col w-full items-start gap-3' >
      <div>
        <p className='mb-2'>Upload Image</p>

        <div className='flex gap-2'>
          <label htmlFor="image1">
            <img className='w-20' src={!image1 ? assets.upload_area: URL.createObjectURL(image1)} alt="" />
            <input onChange={(e)=> setImage1(e.target.files[0])} type="file" id="image1" hidden />
          </label>
          <label htmlFor="image2">
            <img className='w-20' src={!image2 ? assets.upload_area: URL.createObjectURL(image2)} alt="" />
            <input onChange={(e)=> setImage2(e.target.files[0])} type="file" id="image2" hidden />
          </label>
          <label htmlFor="image3">
            <img className='w-20' src={!image3 ? assets.upload_area: URL.createObjectURL(image3)} alt="" />
            <input onChange={(e)=> setImage3(e.target.files[0])} type="file" id="image3" hidden />
          </label>
          <label htmlFor="image4">
            <img className='w-20' src={!image4 ? assets.upload_area: URL.createObjectURL(image4)} alt="" />
            <input onChange={(e)=> setImage4(e.target.files[0])} type="file" id="image4" hidden />
          </label>
        </div>
      </div>

      <div className='w-full'>
        <p className='mb-2'>Product name</p>
        <input onChange={(e) => setName(e.target.value)} value={name} className='w-full max-w-[500px] px-3 py-2' type="text" placeholder='Type here' required />
      </div>
      <div className='w-full'>
        <p className='mb-2'>Product description</p>
        <textarea onChange={(e) => setDescription(e.target.value)} value={description} className='w-full max-w-[500px] px-3 py-2' type="text" placeholder='Write content here' required />
      </div>

      <div className='flex flex-col sm:flex-row gap-2 w-full sm:gap-8'>
        <div>
          <p className='mb-2'>Product Category</p>
          <select onChange={(e) => setCategory(e.target.value)} className='w-full px-3 py-2'>
            <option value="Men">Men</option>
            <option value="Women">Women</option>
            <option value="Kids">Kids</option>
            <option value="Foods">Foods</option>
            <option value="Gadgets">Gadgets</option>
          </select>
        </div>
        <div>
          <p className='mb-2'>Sub Category</p>
          <select onChange={(e) => setSubCategory(e.target.value)} className='w-full px-3 py-2'>
            <option value="Topwear">Topwear</option>
            <option value="Bottomwear">Bottomwear</option>
            <option value="Winterwear">Winterwear</option>
            <option value="Main Dish">Main Dish</option>
            <option value="Breakfast Favourites">Breakfast Favourites</option>
            <option value="Smart Phones">Smart Phones</option>
          </select>
        </div>
        <div>
          <p className='mb-2'>Product Price</p>
          <input onChange={(e)=> setPrice(e.target.value)} value={price} className='w-full px-3 py-2 sm:w-[120px]' type="Number" placeholder='25' />
        </div>
      </div>

      <div>
        <p className='mb-2'>Product Sizes</p>
        <div className='flex gap-3'>
          <div onClick={() => setSizes(prev => prev.includes("S")? prev.filter(item => item !== 'S'):[...prev,"S"])}>
            <p className={`${sizes.includes('S') ?  "bg-pink-100" : "bg-slate-200"} bg-slate-200 px-3 py-1 cursor-pointer`}>S</p>
          </div>
          <div onClick={() => setSizes(prev => prev.includes("M")? prev.filter(item => item !== 'M'):[...prev,"M"])}>
            <p className={`${sizes.includes('M') ?  "bg-pink-100" : "bg-slate-200"} bg-slate-200 px-3 py-1 cursor-pointer`}>M</p>
          </div>
          <div onClick={() => setSizes(prev => prev.includes("L")? prev.filter(item => item !== 'L'):[...prev,"L"])}>
            <p className={`${sizes.includes('L') ?  "bg-pink-100" : "bg-slate-200"} bg-slate-200 px-3 py-1 cursor-pointer`}>L</p>
          </div>
          <div onClick={() => setSizes(prev => prev.includes("XL")? prev.filter(item => item !== 'XL'):[...prev,"XL"])}>
            <p className={`${sizes.includes('XL') ?  "bg-pink-100" : "bg-slate-200"} bg-slate-200 px-3 py-1 cursor-pointer`}>XL</p>
          </div>
          <div onClick={() => setSizes(prev => prev.includes("XXL")? prev.filter(item => item !== 'XXL'):[...prev,"XXL"])}>
            <p className={`${sizes.includes('XXL') ?  "bg-pink-100" : "bg-slate-200"} bg-slate-200 px-3 py-1 cursor-pointer`}>XXL</p>
          </div>
        </div>
      </div>

      <div className='flex gap-2 mt-2'>
        <input onChange={()=> setBestSeller(prev => !prev)} checked={bestseller} type="checkbox" id="bestseller" />
        <label className='cursor-pointer' htmlFor="bestseller">Add to bestseller</label>
      </div>

      <button type="submit" className='w-28 py-3 mt-4 bg-black text-white'>ADD</button>
    </form>
  )
}

export default Add

Turnstile do not show on safari

I’m facing a problem with turnstile integration, I need it to be initially rendered on my page not depending on browser I use. Everything works perfectly on chrome browser, but when I try to open login form on safari my turnstile just don’t appear on page. Sometimes it loads as expected or when I switch pages, but it takes about 30seconds, but it works only 2 out of 10 tries. Stack is: Next.js + js

I thought there were problems with useEffect or with next-turnstile, but found out that problem is not there, I tried cleaning cookies and browser storage, even opened in incognito, nothing helped to debug the problem.

How I load turnstile initially

  useEffect(() => {
   
   function loadTurn(){
    if(!useEffectCheck){
      
      setShowTurnstile(false); // Make Turnstile visible again
      setTimeout(() => {
        setTurnstileStatus("required"); // Reset status and show Turnstile after a delay
        setShowTurnstile(true); // Make Turnstile visible again
      }, 1000); // Optional delay before showing Turnstile again
    }else{
      return
    }
    
   } 
   loadTurn()
   setUseEffectCheck(true)
  }, []); 

How my turnstile looks:

     <Turnstile
                    siteKey={process.env.NEXT_PUBLIC_TURNSTILE_SITE_KEY}
                    retry="auto"
                    refreshExpired="auto"
                    theme="auto"
                    key={showTurnstile + "harry"}
                    onError={() => {
                      setTurnstileStatus("error");
                      console.log("Security check failed. Reload the Page.");
                    }}
                    onExpire={() => {
                      setTurnstileStatus("expired");
                      console.log("Security check expired. Reload the Page.");
                    }}
                    onVerify={() => {
                      setTurnstileStatus("success");
                      setError(null);
                    }}
                    onLoad={() => {
                      setTurnstileStatus("required");
                    }}
                  />

On safari it looks like that, when it’s not loaded:

this how it looks in safari

How to change CSS object-position Y value dynamically

HTML newb here, I recently recorded 3 camera angles of an hour long family event, synced the clips, trimmed them to the exact same length, they’re all 720p 25fps, and I stacked them vertically into a single 1280×2160 25fps MP4 that will be put on a web server I’ve setup. My intent is to switch between different camera angles using CSS object-position Y value. That works as expected when I set the Y value explicitly in the CSS,but I would like to add 3 buttons that can dynamically change the Y value via onClick.

object-position: 0px 0px;

The 2nd value needs to be -720px, or -1440px to show the 2nd and 3rd parts of the video, so how could I simply apply those values using OnClick with a button?

I tried to define a variable, place the variable in object-position, and change the value using onClick and .innerHTML

:root { --camposition: 0; }

<button type="button" onClick="document.getElementById('--camposition').innerHTML='-720px';">Guests</button>

Thanks in advance for any help, googling was a deeeeep dive, hence my reaching out to the wonderful stack overflow community 🙂

ReferenceError: jest is not defined ; (Migrating test case from jest to vitest)

Wanted to migrate the test file from jest to vitest, so modified the code a bit accordingly, but facing an error.

I guess what would work is mocking a storage mock which i was not able to come up with.

// SKIP_LOCALSTORAGE_CHECK
import React from 'react';
import { MockedProvider } from '@apollo/react-testing';
import {
  act,
  render,
  screen,
  fireEvent,
  cleanup,
  waitFor,
} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
// import 'jest-localstorage-mock';
// import 'jest-location-mock';
import { I18nextProvider } from 'react-i18next';
import { Provider } from 'react-redux';
import { BrowserRouter } from 'react-router-dom';
import { store } from 'state/store';
import { StaticMockLink } from 'utils/StaticMockLink';
import i18nForTest from 'utils/i18nForTest';
import OrgList from './OrgList';

import {
  MOCKS,
  MOCKS_ADMIN,
  MOCKS_EMPTY,
  MOCKS_WITH_ERROR,
} from './OrgListMocks';
import { ToastContainer, toast } from 'react-toastify';

// jest.setTimeout(30000);
import useLocalStorage from 'utils/useLocalstorage';
import { vi } from 'vitest';

const { setItem } = useLocalStorage();

async function wait(ms = 100): Promise<void> {
  await act(() => {
    return new Promise((resolve) => {
      setTimeout(resolve, ms);
    });
  });
}

afterEach(() => {
  localStorage.clear();
  cleanup();
  vi.clearAllMocks();
});

describe('Organisations Page testing as SuperAdmin', () => {
  setItem('id', '123');
  const link = new StaticMockLink(MOCKS, true);
  const link2 = new StaticMockLink(MOCKS_EMPTY, true);
  const link3 = new StaticMockLink(MOCKS_WITH_ERROR, true);

  const formData = {
    name: 'Dummy Organization',
    description: 'This is a dummy organization',
    address: {
      city: 'Kingston',
      countryCode: 'JM',
      dependentLocality: 'Sample Dependent Locality',
      line1: '123 Jamaica Street',
      line2: 'Apartment 456',
      postalCode: 'JM12345',
      sortingCode: 'ABC-123',
      state: 'Kingston Parish',
    },
    image: new File(['hello'], 'hello.png', { type: 'image/png' }),
  };
  test('Should display organisations for superAdmin even if admin For field is empty', async () => {
    window.location.assign('/');
    setItem('id', '123');
    setItem('SuperAdmin', true);
    setItem('AdminFor', []);

    render(
      <MockedProvider addTypename={false} link={link}>
        <BrowserRouter>
          <Provider store={store}>
            <I18nextProvider i18n={i18nForTest}>
              <OrgList />
            </I18nextProvider>
          </Provider>
        </BrowserRouter>
      </MockedProvider>,
    );

    await wait();
    expect(
      screen.queryByText('Organizations Not Found'),
    ).not.toBeInTheDocument();
  });
});

This error arises with all the test cases sharing one here

I tried Mocking a vi.fn() but wasn’t able to work it put can anyone help me with this.

checkbox cannot be selected after event redistribution [closed]

I need to adjust the values of certain properties in the event object and bubble up the adjusted event object.

I cloned a new event object based on the original event object, adjusted certain property values on the new object and redistributed the events.

Logically, the checkbox should be selected, but it’s not selected here, can anyone help me find out what’s causing this?

const input = document.querySelector('#checkbox')
input.addEventListener('click', (evt) => {
  if (!evt.__cloned) {

    const init = {}
    for (const evtKey in evt) {
      if (evtKey === 'isTrusted') continue
      init[evtKey] = evt[evtKey]
    }

    init.clientX = init.clientX * 2
    init.clientY = init.clientY * 2

    const cloneEvent = new MouseEvent('click', init)
    cloneEvent.__cloned = true

    evt.preventDefault()
    evt.stopImmediatePropagation()

    evt.target.dispatchEvent(cloneEvent)
  } else {
    console.log('do something...')
  }
})
<input id="checkbox" type="checkbox" />
<label for="checkbox">This is label</label>

Wrong order of css declarations when using `all: unset` and cssText

I am trying to copy styles from document head to picture in picture window. The app is using stitches js which is manipulating CSSOM directly. So I have to copy all styles from StyleSheetList, which mostly works, but found one issue. When there is all: unset it is expanded to all declarations and has wrong order. All testing in Chrome.

For example

button {
  all: unset;
  border-radius: 12px;
}

is copied like this:

button {
...
 block-size: unset;
 border-block: unset;
 border: unset;
 border-radius: 12px;                  <-- border radius set
 border-collapse: unset;
 border-end-end-radius: unset;         <-- border radius is unset here
 border-end-start-radius: unset;
 border-inline: unset;
 border-start-end-radius: unset;
 border-start-start-radius: unset;
...
}

Simplified code to copy styles:

[...document.styleSheets].forEach((styleSheet) => {
  try {
    const style = document.createElement("style");
    style.textContent = [...styleSheet.cssRules].map(({cssText}) => cssText).join("");
    pipDocument.head.appendChild(style);
  } catch (e) {}
});

documentation reference:
https://developer.mozilla.org/en-US/docs/Web/API/StyleSheetList
https://developer.mozilla.org/en-US/docs/Web/API/CSSRule/cssText

It is visible in this snippet:

const styleEl = document.createElement("style");
document.head.appendChild(styleEl);
const sheet = styleEl.sheet;
sheet.insertRule(
  ".test1 { all: unset; background-color: lightblue; border-radius: 12px; padding: 12px; }",
  sheet.cssRules.length
);

const allCSS = [...document.styleSheets]
  .map((styleSheet) => {
    try {
      return [...styleSheet.cssRules].map((rule) => rule.cssText).join("");
    } catch (e) {}
  })
  .filter(Boolean)
  .join("n");
  
const modifiedCSS = allCSS.replace(".test1", ".test2");

const newStyleEl = document.createElement("style");
newStyleEl.innerHTML = modifiedCSS;
document.head.appendChild(newStyleEl);

const divElement = document.createElement("div");
divElement.innerHTML = `<pre>${allCSS}</pre>`;
document.body.appendChild(divElement);
<!DOCTYPE html>
<html lang="en">
  <head>
  
  </head>
  <body>
    <div class="test1">test</div>
    <div class="test2">test copied</div>
    <script src="index.js"></script>
  </body>
</html>

How can I use pagination in DataTable used in cakePHP2

I’m trying to use serverSide: true with DataTables in an older CakePHP project (CakePHP Version: 2.x), but I’m running into issues. When I enable the server-side option, the table doesn’t load correctly—instead, it just displays the raw JSON response.

Here’s my JavaScript code for initializing the DataTable:

$('#tier-management-table').DataTable({ "stateSave": true, "pageLength": 200, "pagingType": 'simple', "processing": true, "serverSide": true, });

And here’s the CakePHP code I’m using to return the data as a JSON response:

$this->set(array( 'response' => $response, '_serialize' => 'response' ));

I’m new to CakePHP and not sure what I’m missing. How can I ensure that the DataTable properly loads the data from the server? Any help would be appreciated!

How to protect the backend API from random access

I’m a beginner in fullstack area. I have a simple Web-APP with a frontend and a backend to show the data from a database. The api call looks like

async function fetchData() {
let res = await axios.get("https://MyAPI-example.com/data");}

To get the data in server with

//some code to connect to Mongodb//
router.get("/data", async (req, res) => {
const data= await collection.find().toArray();
res.send(data).status(200);

Now i realized if people somehow get the API “https://MyAPI-example.com/data”, then they can see my data from everywhere.
Is there any way to make sure that the API can only be called or give response with certain conditions?