Jest mock a function which instantiates a class and its constructor has an error callback, callback not invoked in error case

I need to satisfy SonarQube for the error case in the code below.

When I run the test code though, it will not fail.

index.js

const mod = require('mod')

function get_modclass(data) {   
    let modclass = new ModClass(data, function(err) {
        if (err) {
            console.log('ERROR: ' + err);
            throw err
        }
    })
    
    return modclass
}

index.spec.js


describe('Test get_modclass', () => {
  jest.resetModules()
  jest.clearAllMocks()

  test('Should fail get_modclass', () => {
    const idx = require('./index.js');
    const mod = require('mod')
   
    jest.mock('mod', () => ({
       ModClass: jest.fn(() => ({
                constructor: (_data, cb) => cb('err'),
       }))
    }))


    try {
        let mc = idx.get_modclass("abc")
    } catch(e) {
       expect(e.message).toEqual('some message')
    }

  })
})

Rather than cb('err') I have tried sending cb(new Error('err message')) to the constructor, but it will still not fail. When I debug, it goes into the idx.get_modclass function, but from there it goes direct to return modclass instead of to the if of the callback.

Help appreciated.

Thanks!

Triggering Storage Event Handler After Child Saves LocalStorage Key In Parent

I haven’t been able to find a similar post anywhere online. I am having issues triggering a Storage event listener after a child popup window saves to its parent’s localStorage. This feels like it should be simple, I’m just not sure if I am on the correct path for accomplishing this.

Environment:

  • Single server, IIS, multiple sites
  • Running PHP 7.4.22 on the server

Usage:

  1. User is filling out a web form
  2. User clicks ‘Search’ button on the form to import data into form fields
  3. Button loads a popup window of a site stored on the same server
  4. Item is searched for and selected
  5. Selected item data fields are stored in localstorage of the window.opener element
  6. ISSUE Listener picks up the key being created and is processed by parent

Current Code (Parent):

    window.addEventListener('storage', function(e) {
        alert('Storage change detected.');
        // Do stuff
    });

Desired Result:

  • Selecting an item saves to localStorage and the change is detected by parent – then processed accordingly

Actual Result:

  • Event listener does not trigger when the ‘storage’ event is triggered by the child. My code will trigger if changes are made IN the parent or in the console, but are not triggered when the localStorage key/value pair is created.

Vuejs how to submit dynamic form array data

I will get error invalid format when I submit my form with array but I really didn’t know what is the problem. I have tried to Json.parse the array but still fail.

How can I submit a form with array? Should I pass the array to a variable first then only submit the variable instead of direct submitting the array?

html:

    <input type="text" align="middle" v-model="domains.one">
    <input type="text" align="middle" v-model="domains.two">

    <button type="button" @click="submit">submit</button>

Vuejs:

new Vue({
  el: "#app",
  data: {
    domains: [{one:""},{two:""}],
  },
  methods: {
    addCompanySetting() {
      var postData = '&domain='+this.domains';
         $.ajax({
                    url:baseUrl+'/agency/account/prefer-ma',
                    type: 'POST',
                    data: postData,
                    dataType: 'json'
                }).done(function (data){
                    if(data.result == "1"){
                       console.log("success");
                    }else{
                        console.log("error");
                    }
                });
        }
}

Github API returns CORS error when using create-react-app

I am trying to download the latest release of a specific private repository. I am able to gather information by using this GET request:

    const token = "{Very secret token not for StackOverflow}";
    const owner = {company};
    
    const response = await fetch(
      `https://api.github.com/repos/${owner}/${repo}/releases/latest`,
      {
        //mode: 'no-cors',
        headers: {
          Authorization: 'Bearer ' + token,
        },
      }
    );

    const log = await response.json();
    console.log(log);
  }

This call returns some data, including the ‘zipball_url’ property, where i think my download comes from. However, if i try to make a request to this URL (including my token), i am getting a nasty CORS error:

Access to fetch at 'https://codeload.github.com/{company}/{reponame}/legacy.zip/refs/tags/1.1.7?token={secret token}' (redirected from 'https://api.github.com/repos/{company}/{reponame}/zipball/1.1.7') from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

The Github API Docs are not helping me very much. Can someone explain me how to fix this?

How to mock one element in an Array in javascript test

I’m writing a javascript test, and am trying to mock one element in an array, I’m not sure this is the correct way to say it, but this is what I’m trying to do.

const arr = [1, 2, 3];
arr[0].mockReturnValue(4); 
//so in the end, I want the array to be [4,2,3] when I pass it into another function. 

Is there anyway I can do this?

How to properly syntax async storage with a globally defined array

I’m trying to keep the history of each time a list is selected and store the name of the list and the time it was selected. I used a global array to store this but I’m not sure how to properly syntax it without receiving errors.

Here is where the array is defined.

var listName = truncate(title) + '  '
    global.historyData.push({createID, listName, currentDate}) 
    console.log(global.historyData);

Stores an ID, list name and current date at that time.

This is a different page that displays the history of the list. I want it to keep the history even when the user reloads the app, hence the async storage.

Here is the second-page code.

global.historyData = useState([]);


const ShoppingHistoryCard = (state, {route}) => {
    React.useEffect(() => {
const fetchHistory = async () => {
    const response = await getItem('{global.historyData}');

    safeDispatch({
        type: 'RESTORE_HISTORY',
        payload: {
            global.historyData: response === null ? [] : response
        }
    });
};

fetchHistory();
}, [safeDispatch]);

React.useEffect(() => {
const saveHistory = async () => {
    await setItem('global.historyData', state?.global.historyData ?? []);
};

if (state.isRestoringHistory === false) {
    saveHistory();
}
}, [state.global.historyData, state.isRestoringHistory]);


const safeDispatch = React.useCallback((...args) => {
if (hasMounted.current === true) {
    dispatch(...args);
}
}, []);


React.useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
  console.log('Refreshed!');
});
return unsubscribe;
  }, [navigation]);

And where the array is irrerated through to display the items.

const renderElements = () => {

let jsx = [];
let varElements = [];

global.historyData.forEach((item) => {
     if (varElements.length > 0) {
       jsx.push(<View style={{flexDirection: 'row'}}>{varElements}</View>);
     }
     varElements = [];
     jsx.push(<Text>{item.listName}{item.currentDate}</Text>);
   }
 );
 return jsx;
};

return(
    <View>
        <Text style={styles.title}>Shopping List History</Text>
            <View style={styles.section}>
                <View style={{width:170}}>
                {renderElements()}
                </View>
        </View>
    </View>
 );
}

How do I get the search parameters to add to the url on submit, not on change?

The URL format is as follows:

www.url.com/keyword=”_____”

However, the ____ portion of the url starts to fill in even before I submit the form? It works on submit as well but I’ve noticed in my console that every letter is being logged
I infer that is because my input is set to onChange instead of onSubmit but after changing it onSubmit it doesn’t work anymore.

The keyword also sticks around after refreshing the page instead of going back to the original base URL sans parrameters, how can I remedy this?

const SearchBox = ({
  onSubmit: onSubmitCallback,
  searchBoxLabel,
  searchBoxPlaceholder,
  searchBoxButtonText,
  searchBoxHeader,
  searchBoxDescription,
  listingType,
}) => {

  const dispatch = useDispatch();
  const keywords = useSelector((state) => state.searchReducer.Keywords);
  const [searchValue, setSearchValue] = useSearchParams({});

  useEffect(() => {
    const queryKeywords = window.location.search.split('=')[1];
    setSearchValue(queryKeywords)
    onSubmitCallback(queryKeywords)
  }, [])


  const handleSubmit = (e) => {
    e.preventDefault();
    onSubmitCallback(keywords);
    setSearchValue({ searchValue: e.target.value });
    dispatch(setFilters([]));
    // clear all checkboxes
    document
      .querySelectorAll("input[type=checkbox]")
      .forEach((el) => (el.checked = false));
      setSearchValue(searchValue)
  };


  return (
 
    
    <div className={
          listingType === "news"     ? "search-banner search-banner--news"
        : listingType === 'global'   ? "search-banner search-banner--global"
        : listingType === 'resources' ? "search-banner search-banner--resources"
        : "search-banner"
      }
    >

      <div className="search-banner__header">
        <h2>{searchBoxHeader}</h2>
        <p>{searchBoxDescription}</p>
      </div>


      <form className="search-banner__form" onSubmit={handleSubmit}>

        <div className="search-banner__keyword-input-group">
          <label
            htmlFor="resource-search"
            className="search-banner__keyword-label"
          >
            {searchBoxLabel}
          </label>
          <input
            type="text"
            id="resource-search"
            className="search-banner__keyword-input"
            placeholder={searchBoxPlaceholder}
            
            onChange={(evt) => {
              setSearchValue({ keyword: evt.target.value })
              dispatch(setKeywords(evt.currentTarget.value))}
            }
          />
        </div>

        <button className={listingType !== 'resources' ? "btn btn-form" : "btn btn-hollow-white"} style={{backgroundColor: `${listingType === 'news' ? '#3F107C' : ''}`}} type="submit">
          {searchBoxButtonText}
        </button>

      </form>


    </div>

  );
};

export default SearchBox;

React components in Electron application won’t show

Good day everyone. I am running an Electron/React application or however you put it. Anyways, I have created three React components and put them into my app.js

import React from "react";
import ReactDOM from "react-dom";
import Search from "./components/search.component";
import Details from "./components/details.component";
import Player from "./components/player.component";

class App extends React.Component {
    render() {
        return (
            <div>
                <Search />
                <Details title={'Track title'} />
                <Player />
            </div>
        );
    }
}

ReactDOM.render(<App />, document.getElementById('content'))

There’s no error that comes from running the application, but none of my components are showing. When I run this as just a regular React application, it does work. Any help would be greatly appreciated!

Bowling game Javascript jest

**Hello I have this program but when I run in a compiler it says I have an error can you please help me. I don’t know where is the problem. here is m code also
**

function bowlingScore(frames) {
    var framesArr = frames.split(' ').map((frame) => [...frame]);
    var result = 0;
    for (var i = 0; i < framesArr.length; i++) {
        var current = framesArr[i];
        if (current[0] === 'X' && i < 9) {
            result += 10 + getNextElementsScore(framesArr, i, 2);
        }
        else if (current.length === 2 && current[1] === '/' && i < 9) {
            result += 10 + getNextElementsScore(framesArr, i, 1);
        }
        else if (current.length === 3) {
            result += getThreeRollScore(current);
        }
        else {
            result += getElementScore(current, 0) + getElementScore(current, 1);
        }
    }
    return result;
}
function getNextElementsScore(framesArr, index, count) {
    var result = getElementScore(framesArr[index + 1], 0);
    var result2 = getElementScore(framesArr[index + 1], 1);
    if (framesArr[index + 1].length === 1) {
        return count === 1 ? result : result + getElementScore(framesArr[index + 2], 0);
    }
    return count === 1 ? result : (result2 === 10 && result !== 10 ? result2 : result2 + result);
}
function getElementScore(frame, index) {
    if (frame[index] === 'X' || frame[index] === '/') {
        return 10;
    }
    return parseInt(frame[index]);
}
function getThreeRollScore(current) {
    var third = getElementScore(current, 2);
    var second = getElementScore(current, 1);
    var first = getElementScore(current, 0);
    return third === 10 && second !== 10 ? third + first : (second === 10 && first !== 10 ? third + second : first + second + third);
}

How to verify certain text is displayed on the page/element?

I’m trying to capture screenshots using selenium webdriver on a page that has textarea with a large scrollable text. I need to capture screenshots of all the texts in the textarea. With my code, I am able to scroll down on the textarea and take screenshots but need to stop once all the texts are shown. Here is the code

    while(!textDisplayedInPage("text at the bottom of textarea element")){
        takeScreenShot();
        scrollDown();
       }
    

public boolean textDisplayedInPage(String text){
    WebElement element = null;
    try{
        element =getDriver().findElement(By.xpath("//*[contains(text(),'"+text+"')]"));
    }catch (Exception e){}
    if(element != null){
        return true;
    };
    return false;
}

problem is the textDisplayedInPage() method doesn’t work and selenium finds the element on the first screen even though it’s not displayed yet and breaks the loop. I have tried few answers that I found of similar issues here but all fails to deliver what’s displayed. Any insight on how to capture or verify displayed text of a scrollable element would help.

How can I create a doughnut chart with rounded corners only on one end of each segment?

I’m trying to build a doughnut chart with rounded corners only on one side. My problem is that I have both sided rounded and not just on the one side. Also can’t figure out how to do more foreground arcs not just one.

    const tau = 2 * Math.PI; // http://tauday.com/tau-manifesto
    const arc = d3.arc()
        .innerRadius(80)
        .outerRadius(100)
        .startAngle(0)
        .cornerRadius(15);
    const svg = d3.select("svg"),
        width = +svg.attr("width"),
        height = +svg.attr("height"),
        g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

Background arc, but I’m not sure if this is even needed?

const background = g.append("path")
        .datum({endAngle: tau})
        .style("fill", "#ddd")
        .attr("d", arc);

    const data = [ .51];
    const c = d3.scaleThreshold()
          .domain([.200,.205,.300,.310, .501, 1])
          .range(["green","#ddd", "orange","#ddd", "red"]);
    Const pie = d3.pie()
          .sort(null)
          .value(function(d) {
            return d;
          });

Only have one foreground, but need to be able to have multiple:

 const  foreground = g.selectAll('.arc')
        .data(pie(data))
        .enter()
        .append("path")
        .attr("class", "arc")
        .datum({endAngle: 3.8})
        .style("fill", function(d) {
            return c(d.value);
          })
        .attr("d", arc)

Expected output:

Expected output

What am I doing wrong?

var tau = 2 * Math.PI; // http://tauday.com/tau-manifesto

// An arc function with all values bound except the endAngle. So, to compute an
// SVG path string for a given angle, we pass an object with an endAngle
// property to the `arc` function, and it will return the corresponding string.
var arc = d3.arc()
    .innerRadius(80)
    .outerRadius(100)
    .startAngle(0)
    .cornerRadius(15);

// Get the SVG container, and apply a transform such that the origin is the
// center of the canvas. This way, we don’t need to position arcs individually.
var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

// Add the background arc, from 0 to 100% (tau).
var background = g.append("path")
    .datum({endAngle: tau})
    .style("fill", "#ddd")
    .attr("d", arc);

var data = [ .51];
var c = d3.scaleThreshold()
      .domain([.200,.205,.300,.310, .501, 1])
      .range(["green","#ddd", "orange","#ddd", "red"]);
var pie = d3.pie()
      .sort(null)
      .value(function(d) {
        return d;
      });
// Add the foreground arc in orange, currently showing 12.7%.
var foreground = g.selectAll('.arc')
    .data(pie(data))
    .enter()
    .append("path")
    .attr("class", "arc")
    .datum({endAngle: 3.8})
    .style("fill", function(d) {
        return c(d.value);
      })
    .attr("d", arc)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="960" height="500"></svg>

How to get audio snippet to play on a condition

So basically I’m just trying to have some fun and do something goofy. I’m in the early stages of my learning so naturally, I’m curious about what I can do.

I made a simple calculator and I want a sound to play if the user adds 420 and 69 together.

Really dumb I know. I think it’s hilarious.

Anyways, I put this code in and I got the sound to play but it starts as soon as I load the page.

     var audio = new Audio("UH OH.mp3");
     audio.play();

What I want to do is for the sound to play only if the calculator gets 489 as a result.

    var audio = new Audio('UH OH.mp3');
    if (currentOperandTextElement == 489) {
    audio.play();
    }

I thought that would work but because I’m a noob I can imagine there’s more to it than that. I tried to figure it out myself but I just want to know so I can learn something.

Trying to eliminate children 3-7 from an element, I am looping through the array to eliminate them but it wont work

So first main has only one child which is why I selected the child blades as var blades = main.children[0]; then I am trying to loop through and just eliminate the children within blades from [3] through [7] but for some reason when doing this on the console it won’t work.

 function deleteBlades() {
        var main = document.getElementById("id-9a1e3f8f48548d4c2c422b1f92cb749a");
        var blades = main.children[0];
        for (var i = 0; i < blades.length; i++) {
            if( i >= 3 || i <= 7)
                {
                    blades.children[i].remove();
                }
        }
    }
    deleteBlades();

Any ideas on what am I doing wrong?

Change AngularJS Input Value

I want to programmatically update the value of an AngulrJS input field model with plain javascript from the browser console.
If I just use element.value = 0.5 it displays the new value but doesnt update the real model value that is associated with the input. Therefore no update event is triggered. Is this possible through the console?