Best JavaScript code snippet using chromeless
App.js
Source:App.js  
1import React, { useState, useEffect, useRef } from 'react';2import {3  Row,4  Col,5  Tab,6  Nav,7  Accordion,8  Card,9  ListGroup,10  Button,11  Form,12  Spinner,13} from 'react-bootstrap';14import ReactGA from 'react-ga';15import {16  BsCheck,17  BsCheckBox,18  BsSquare,19  BsFillInfoCircleFill,20} from 'react-icons/bs';21import queryString from 'query-string';22import { PDFDocument } from 'pdf-lib';23import spbQuestions from './questions-spb-random';24import spbRecommendations from './recommendations-spb';25import mwmQuestions from './questions-mwm-random';26import mwmRecommendations from './recommendations-mwm';27const canViewResults = false;28const trackingId = 'UA-62474262-1'; // Replace with your Google Analytics tracking ID29ReactGA.initialize(trackingId);30const assetBase =31  typeof window !== 'undefined' && window.ENVIRONMENT === 'production'32    ? 'https://capabilitysource.com'33    : '';34const parseQS = queryString.parse(35  typeof window !== 'undefined' ? window.location.search : ''36);37let csAnswers;38let csAutoAnswer = false;39const csFormType = window.CS_FORM || process.env.CS_FORM || 'mwm';40const trackEvent = (action, label) => {41  console.log('Tracking', action, label);42  ReactGA.event({43    category: `${44      csFormType === 'spb' ? 'Readiness' : 'Benchmark Assessment'45    } Form`,46    action,47    label,48  });49};50if (parseQS['CS-ANSWERS']) {51  csAnswers = JSON.parse(parseQS['CS-ANSWERS']);52}53if (parseQS['CS-AUTO-ANSWERS']) {54  csAutoAnswer = true;55}56const csAgreed =57  typeof window !== 'undefined' && window.CS_AGREED ? window.CS_AGREED : false;58const validateEmail = (email) => {59  // eslint-disable-next-line no-control-regex60  const expression =61    /(?!.*\.{2})^([a-z\d!#$%&'*+\-/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+(\.[a-z\d!#$%&'*+\-/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)*|"((([ \t]*\r\n)?[ \t]+)?([\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*(([ \t]*\r\n)?[ \t]+)?")@(([a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|[a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF][a-z\d\-._~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*[a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])\.)+([a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|[a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF][a-z\d\-._~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*[a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])\.?$/i;62  return expression.test(String(email).toLowerCase());63};64const getScoreLabel = (score) =>65  score > 7566    ? 'Optimized'67    : score > 5068    ? 'Managed'69    : score > 2570    ? 'Basic'71    : 'Adhoc';72const alertUser = async (formType, toObj, ResultsPDF) => {73  await fetch('https://mandrillapp.com/api/1.0/messages/send-template.json', {74    method: 'POST', // *GET, POST, PUT, DELETE, etc.75    mode: 'cors', // no-cors, *cors, same-origin76    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached77    credentials: 'same-origin', // include, *same-origin, omit78    headers: {79      'Content-Type': 'application/json',80      // 'Content-Type': 'application/x-www-form-urlencoded',81    },82    redirect: 'follow', // manual, *follow, error83    referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url84    body: JSON.stringify({85      key: '6SVyLcjG9Lt6Ff_UD_1JuA',86      template_name:87        formType === 'spb'88          ? 'spb-readiness-calculator'89          : 'mom-benchmark-calculator',90      template_content: [91        {92          name: 'example name',93          content: 'example content',94        },95      ],96      message: {97        to: [98          {99            email: toObj.email,100            name: toObj.name,101            type: 'to',102          },103        ],104        attachments: [105          {106            type: 'application/pdf',107            name: `${108              formType === 'cs-mwm-results'109                ? 'Marketing Operations Maturity Benchmark Assessment Results'110                : formType111            }.pdf`,112            content: ResultsPDF,113          },114        ],115      },116    }), // body data type must match "Content-Type" header117  });118  return true;119};120const alertCS = async (toObj, link) => {121  await fetch('https://mandrillapp.com/api/1.0/messages/send-template.json', {122    method: 'POST', // *GET, POST, PUT, DELETE, etc.123    mode: 'cors', // no-cors, *cors, same-origin124    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached125    credentials: 'same-origin', // include, *same-origin, omit126    headers: {127      'Content-Type': 'application/json',128      // 'Content-Type': 'application/x-www-form-urlencoded',129    },130    redirect: 'follow', // manual, *follow, error131    referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url132    body: JSON.stringify({133      key: '6SVyLcjG9Lt6Ff_UD_1JuA',134      template_name: 'notify-survey-taken',135      template_content: [136        {137          name: 'example name',138          content: 'example content',139        },140      ],141      message: {142        to: [143          {144            email: 'solutions@capabilitysource.com',145            name: 'CapabilitySource',146            type: 'to',147          },148        ],149        global_merge_vars: [150          {151            name: 'SUBMITTED_NAME',152            content: toObj.name,153          },154          {155            name: 'SUBMITTED_EMAIL',156            content: toObj.email,157          },158          {159            name: 'SURVEY_LINK',160            content: link,161          },162        ],163      },164    }), // body data type must match "Content-Type" header165  });166  return true;167};168const createPdf = async (formType, info, link, surveyScores) => {169  const ratio = 0.24;170  const pdfFormType = formType === 'mwm' ? 'mom' : formType;171  await Promise.all([172    fetch(`${assetBase}/static/pdf-${pdfFormType}/first-page.pdf`),173    fetch(174      `${assetBase}/static/pdf-${pdfFormType}/people-${getScoreLabel(175        surveyScores.People176      ).toLowerCase()}.pdf`177    ),178    fetch(179      `${assetBase}/static/pdf-${pdfFormType}/process-${getScoreLabel(180        surveyScores.Process181      ).toLowerCase()}.pdf`182    ),183    fetch(184      `${assetBase}/static/pdf-${pdfFormType}/technology-${getScoreLabel(185        surveyScores.Technology186      ).toLowerCase()}.pdf`187    ),188    fetch(189      `${assetBase}/static/pdf-${pdfFormType}/information-${getScoreLabel(190        surveyScores.Information191      ).toLowerCase()}.pdf`192    ),193    fetch(`${assetBase}/static/pdf-${pdfFormType}/last-page.pdf`),194    fetch(195      `${assetBase}/static/pdf-common/people-${getScoreLabel(196        surveyScores.People197      ).toLowerCase()}.png`198    ),199    fetch(200      `${assetBase}/static/pdf-common/process-${getScoreLabel(201        surveyScores.Process202      ).toLowerCase()}.png`203    ),204    fetch(205      `${assetBase}/static/pdf-common/technology-${getScoreLabel(206        surveyScores.Technology207      ).toLowerCase()}.png`208    ),209    fetch(210      `${assetBase}/static/pdf-common/information-${getScoreLabel(211        surveyScores.Information212      ).toLowerCase()}.png`213    ),214  ])215    .then((responses) =>216      // Get a JSON object from each of the responses217      Promise.all(responses.map((response) => response.arrayBuffer()))218    )219    .then(async (data) => {220      const returnPdf = await PDFDocument.create();221      const firstPage = await returnPdf.copyPages(222        await PDFDocument.load(data[0]),223        [0]224      );225      const peoplePage = await returnPdf.copyPages(226        await PDFDocument.load(data[1]),227        [0]228      );229      const processPage = await returnPdf.copyPages(230        await PDFDocument.load(data[2]),231        [0]232      );233      const technologyPage = await returnPdf.copyPages(234        await PDFDocument.load(data[3]),235        [0]236      );237      const informationPage = await returnPdf.copyPages(238        await PDFDocument.load(data[4]),239        [0]240      );241      const lastPage = await returnPdf.copyPages(242        await PDFDocument.load(data[5]),243        [0]244      );245      returnPdf.addPage(firstPage[0]);246      returnPdf.addPage(peoplePage[0]);247      returnPdf.addPage(processPage[0]);248      returnPdf.addPage(technologyPage[0]);249      returnPdf.addPage(informationPage[0]);250      returnPdf.addPage(lastPage[0]);251      const peopleBar = await returnPdf.embedPng(data[6]);252      const processBar = await returnPdf.embedPng(data[7]);253      const technologyBar = await returnPdf.embedPng(data[8]);254      const informationBar = await returnPdf.embedPng(data[9]);255      returnPdf.getPage(0).drawImage(peopleBar, {256        x: 1650 * ratio,257        y: 2469 * ratio,258        width: 424 * ratio,259        height: 1200 * ratio,260      });261      returnPdf.getPage(0).drawImage(processBar, {262        x: 2249 * ratio,263        y: 2469 * ratio,264        width: 424 * ratio,265        height: 1200 * ratio,266      });267      returnPdf.getPage(0).drawImage(technologyBar, {268        x: 2840 * ratio,269        y: 2469 * ratio,270        width: 424 * ratio,271        height: 1200 * ratio,272      });273      returnPdf.getPage(0).drawImage(informationBar, {274        x: 3438 * ratio,275        y: 2469 * ratio,276        width: 424 * ratio,277        height: 1200 * ratio,278      });279      const base64Pdf = await returnPdf.saveAsBase64();280      // const blob = new Blob([pdfBytes], { type: 'application/pdf' });281      // const invisAnchor = document.createElement('a');282      // invisAnchor.href = window.URL.createObjectURL(blob);283      // invisAnchor.download = 'SPB-Results.pdf';284      // invisAnchor.click();285      await alertCS(info, link);286      await alertUser(formType, info, base64Pdf);287      if (window.CS_FORM_REDIRECT) {288        window.location.href = window.CS_FORM_REDIRECT;289      }290      return true;291    })292    .catch(() => {293      // console.error(error)294    });295  return true;296};297const makeAnswers = (Data) => {298  const results = {};299  Object.keys(Data).map((area) => {300    results[area] = Array.from(Array(Data[area].length), () =>301      csAutoAnswer ? Math.floor(Math.random() * 4) + 1 : 0302    );303    return null;304  });305  return results;306};307const makeViewQuestions = (Data) => {308  const results = {};309  Object.keys(Data).map((key) => {310    results[key] = 0;311    return null;312  });313  return results;314};315function App() {316  const formType = csFormType;317  const seenChart = useRef(false);318  const selectedAnswer = useRef(false);319  const formEmail = useRef();320  const formName = useRef();321  // const Questions = formType === 'spb' ? spbQuestions : mwmQuestions;322  const Recommendations =323    formType === 'spb' ? spbRecommendations : mwmRecommendations;324  const [agreed, setAgreed] = useState(csAgreed);325  const [Questions, setQuestions] = useState(326    formType === 'spb' ? spbQuestions : mwmQuestions327  );328  const [showFormError, setShowFormError] = useState(false);329  const [allAgreement, setAllAgreement] = useState(false);330  const [showChart, setShowChart] = useState(false);331  const [showGetPdf, setShowGetPdf] = useState(false);332  const [sendingPdf, setSendingPdf] = useState(false);333  const [showCalculate, setShowCalculate] = useState(false);334  const [scores, setScores] = useState({});335  const [viewResult, setViewResult] = useState();336  const [answers, setAnswers] = useState(csAnswers || makeAnswers(Questions));337  const [viewQuestion, setViewQuestion] = useState(338    makeViewQuestions(Questions)339  );340  const [viewArea, setViewArea] = useState(Object.keys(Questions)[0]);341  const ref = useRef(null);342  const loaded = useRef();343  const getContactClick = () => {344    const FormAnswers = `${window.location.protocol}//${window.location.host}${345      window.location.pathname346    }?CS-ANSWERS=${encodeURIComponent(JSON.stringify(answers))}`;347    return FormAnswers;348  };349  const turnOffResult = () => {350    if (viewResult) {351      setViewResult(null);352    }353  };354  useEffect(() => {355    const randomOrder = () => {356      const newQuestions = {};357      Object.keys(Questions).map((area) => {358        newQuestions[area] = Questions[area].map((question) => ({359          ...question,360          answersOrder: [0].concat(361            [1, 2, 3, 4].sort(() => 0.5 - Math.random())362          ),363        }));364        return null;365      });366      setQuestions(newQuestions);367      trackEvent(368        `Started form: ${formType === 'spb' ? 'Readiness' : 'Benchmark'}`369      );370    };371    if (Questions && !Questions.People[0].answersOrder) {372      randomOrder();373    }374  }, [Questions]);375  useEffect(() => {376    window.addEventListener('click', turnOffResult);377    return function cleanup() {378      window.removeEventListener('click', turnOffResult);379    };380  });381  const setViewingQuestion = (area, index) => {382    const newViewQuestion = { ...viewQuestion };383    newViewQuestion[area] = index;384    setViewQuestion(newViewQuestion);385  };386  const answered = async (questionArea, questionIndex, score) => {387    const newAnswers = { ...answers };388    const allAreas = Object.keys(newAnswers);389    newAnswers[questionArea][questionIndex] = score;390    selectedAnswer.current = true;391    const areaUnanswered = (area) =>392      Math.max(393        newAnswers[area].indexOf(0),394        newAnswers[area]395          .slice(viewQuestion[area] + (area === questionArea ? 1 : 0))396          .indexOf(0) > -1397          ? newAnswers[area]398              .slice(viewQuestion[area] + (area === questionArea ? 1 : 0))399              .indexOf(0) +400              viewQuestion[area] +401              (area === questionArea ? 1 : 0)402          : -1403      );404    const firstUnansweredQuestionByArea = allAreas.map((area) =>405      areaUnanswered(area)406    );407    const unansweredAreas = firstUnansweredQuestionByArea.map((thisAnswer) =>408      thisAnswer > -1 ? 1 : 0409    );410    const goToArea = Math.max(411      unansweredAreas.indexOf(1),412      unansweredAreas.slice(allAreas.indexOf(questionArea)).indexOf(1) > -1413        ? unansweredAreas.slice(allAreas.indexOf(questionArea)).indexOf(1) +414            allAreas.indexOf(questionArea)415        : -1416    );417    if (goToArea > -1) {418      setViewArea(allAreas[goToArea]);419      setViewingQuestion(420        allAreas[goToArea],421        areaUnanswered(allAreas[goToArea])422      );423      setTimeout(() => {424        const showQuestion =425          typeof document !== 'undefined'426            ? document.getElementById(427                `question:${goToArea}:${areaUnanswered(allAreas[goToArea])}`428              )429            : null;430        if (showQuestion && loaded.current && typeof document !== 'undefined') {431          document432            .getElementById(433              `question:${goToArea}:${areaUnanswered(allAreas[goToArea])}`434            )435            .scrollIntoView({ behavior: 'smooth', block: 'start' });436        }437        loaded.current = true;438      }, 500);439    } else if (!seenChart.current) {440      seenChart.current = true;441      if (canViewResults) {442        setShowChart(true);443        trackEvent('Opened results');444      } else {445        setShowCalculate(true);446        trackEvent('Sending results');447        // TODO: GET THE EMAIL AND WHAT NOT, REDIRECT WHEN DONE448        await createPdf(449          formType,450          {451            email: window.CS_FORM_EMAIL,452            name: window.CS_FORM_NAME,453          },454          getContactClick(),455          scores456        );457      }458    }459    setAnswers(newAnswers);460  };461  const areaComplete = (area) => {462    let completed = 0;463    answers[area].map((score) => {464      completed += score > 0 ? 1 : 0;465      return null;466    });467    return completed >= 4;468  };469  const canViewChart = () => {470    let passCount = 0;471    Object.keys(answers).map((area) => {472      passCount += areaComplete(area) ? 1 : 0;473      return null;474    });475    return passCount === Object.keys(answers).length;476  };477  useEffect(() => {478    const newScores = {};479    const getScore = (area) => {480      const areaAnswers = answers[area];481      let thisAnswered = 0;482      let totalScore = 0;483      areaAnswers.map((score) => {484        totalScore += score;485        thisAnswered += score > 0 ? 1 : 0;486        return null;487      });488      return Math.round(489        totalScore > 0 && thisAnswered > 0490          ? (totalScore / (thisAnswered * 4)) * 100491          : 0492      );493    };494    Object.keys(answers).map((area) => {495      newScores[area] = getScore(area);496      return null;497    });498    setScores(newScores);499  }, [answers]);500  useEffect(() => {501    if (typeof document !== 'undefined' && selectedAnswer.current === true) {502      document503        .getElementById('cs-widget-chart')504        .scrollIntoView({ behavior: 'smooth', block: 'start' });505    }506  }, [showChart]);507  return (508    <>509      <div ref={ref} id="cs-widget-chart" className="bg-white">510        {!agreed ? (511          <Row className="justify-content-center">512            <Col className="text-center">513              <h2 style={{ maxWidth: '600px', margin: '0 auto 1rem auto' }}>514                {formType === 'spb'515                  ? 'Planning Agility Benchmark'516                  : 'Marketing Operations Maturity Benchmark Assessment'}517              </h2>518              <p>519                Answer a minimum of 4 questions in each section to{' '}520                {canViewResults ? 'view' : 'access'} results.521              </p>522              <small className="mb-3 d-block">523                <em>524                  By using the{' '}525                  {formType === 'spb' ? 'Readiness' : 'Benchmark Assessment'}{' '}526                  Calculator, you agree to the{' '}527                  <a528                    href="#0"529                    onClick={() => {530                      setAllAgreement(!allAgreement);531                      trackEvent('Agreed Terms of Use');532                    }}533                  >534                    Terms of Use535                  </a>536                  .537                </em>538              </small>539              {allAgreement ? (540                <div541                  className="p-3 mb-3 border text-left"542                  style={{ height: '200px', overflowY: 'auto' }}543                >544                  <p>545                    Use of the{' '}546                    {formType === 'spb' ? 'Readiness' : 'Benchmark Assessment'}{' '}547                    Calculator and submission of your data via the online form548                    is voluntary. By using the{' '}549                    {formType === 'spb' ? 'Readiness' : 'Benchmark Assessment'}{' '}550                    Calculator, you agree to share your data and responses with551                    CapabilitySource. Upon submission of your data,552                    CapabilitySource will generate online content, and a report553                    will be distributed to the email address you provide. In554                    providing an email address you attest to be the owner of the555                    address and agree to receive communications from556                    CapabilitySource at the address.557                  </p>558                  <p>559                    The content on this website is for convenience and560                    information purposes only. Your submission does not create a561                    contract, whether implied or expressed, between you and562                    CapabilitySource or its partners. However, we welcome the563                    opportunity for future discussions regarding ways564                    CapabilitySource can assist you with your marketing565                    strategies. Any information you provide will be considered566                    non-confidential. We will not disclose, sell or rent this567                    information without your express written permission.568                  </p>569                  <p>570                    Should you choose to use a{' '}571                    {formType === 'spb' ? 'Readiness' : 'Benchmark Assessment'}{' '}572                    Calculator on this website; information collected from you573                    will be used for the purpose of understanding your business574                    needs and responding accordingly. We may contact you via575                    email or phone. You may choose to opt out of future576                    communications at any time by contacting us at577                    <a href="mailto:privacy@capabilitysource.com">578                      privacy@capabilitysource.com579                    </a>580                    .581                  </p>582                </div>583              ) : null}584              <Button585                size="lg"586                className="button-getintouch mx-2 mb-3"587                onClick={() => {588                  setAgreed(true);589                }}590              >591                Calculate{' '}592                {formType === 'spb' ? 'Readiness' : 'Benchmark Assessment'}593              </Button>594            </Col>595          </Row>596        ) : !showChart ? (597          <>598            <Row>599              <Col>600                <Tab.Container activeKey={viewArea}>601                  <Row>602                    <Col md={3} className="d-none d-md-block">603                      <Nav variant="pills" className="flex-column">604                        {Object.keys(Questions).map((area) => (605                          <Nav.Item key={`tab:${area}`}>606                            <Nav.Link607                              eventKey={area}608                              className={`${area} d-flex align-items-center`}609                              onClick={() => {610                                setViewArea(area);611                                trackEvent('Opened area', area);612                              }}613                            >614                              {area}615                              <BsCheck616                                size="2rem"617                                className={`ml-auto${618                                  !areaComplete(area) ? ' invisible' : ''619                                }`}620                              />621                            </Nav.Link>622                          </Nav.Item>623                        ))}624                      </Nav>625                      <Button626                        size="lg"627                        className="mt-5 mb-3 button-results"628                        block629                        disabled={!canViewChart()}630                        onClick={async () => {631                          if (canViewResults) {632                            setShowChart(true);633                            trackEvent('Opened results');634                          } else {635                            setShowCalculate(true);636                            trackEvent('Sending results');637                            // TODO: GET THE EMAIL AND WHAT NOT, REDIRECT WHEN DONE638                            await createPdf(639                              formType,640                              {641                                email: window.CS_FORM_EMAIL,642                                name: window.CS_FORM_NAME,643                              },644                              getContactClick(),645                              scores646                            );647                          }648                        }}649                        variant="custom"650                      >651                        {canViewResults ? 'VIEW' : 'GET'} RESULTS652                      </Button>653                      {!canViewChart() ? (654                        <small className="text-center d-block mx-3">655                          Answer a minimum of 4 questions in each section to{' '}656                          {canViewResults ? 'views' : 'access'} results.657                        </small>658                      ) : null}659                    </Col>660                    <Col md={9}>661                      <Row662                        noGutters663                        className="d-flex d-md-none survey-top-nav"664                        xs="2"665                        sm="4"666                      >667                        {Object.keys(Questions).map((area) => (668                          <Col key={`topnav:${area}`}>669                            <Button670                              variant="link"671                              className={`${area} ${672                                area === viewArea ? 'active' : ''673                              } d-flex align-items-center justify-content-center`}674                              onClick={() => {675                                setViewArea(area);676                                trackEvent('Opened area', area);677                              }}678                            >679                              {area}680                              {areaComplete(area) ? (681                                <BsCheck className="ml-2" size="1.5rem" />682                              ) : null}683                            </Button>684                          </Col>685                        ))}686                      </Row>687                      <Tab.Content className="text-left">688                        {Object.keys(Questions).map((area, areaIndex) => (689                          <Tab.Pane690                            eventKey={area}691                            key={`tabpane:${area}`}692                            className={area}693                          >694                            <Accordion695                              activeKey={`question:${area}:${viewQuestion[area]}`}696                            >697                              {Questions[area].map(698                                (question, questionsIndex) => (699                                  <Card700                                    key={`question:${area}:${questionsIndex.toString()}`}701                                  >702                                    <Accordion.Toggle703                                      id={`question:${areaIndex}:${questionsIndex}`}704                                      as={Card.Header}705                                      eventKey={`question:${area}:${questionsIndex.toString()}`}706                                      className={`d-flex align-items-center${707                                        viewQuestion[area] === questionsIndex708                                          ? ' selected'709                                          : ''710                                      }`}711                                      onClick={() => {712                                        setViewingQuestion(713                                          area,714                                          questionsIndex715                                        );716                                        trackEvent(717                                          'Opened question',718                                          `${area}: [${questionsIndex.toString()}]${719                                            question.question720                                          }`721                                        );722                                      }}723                                    >724                                      <div className="d-inline-flex">725                                        {answers[area][questionsIndex] > 0 ? (726                                          <BsCheckBox727                                            className="mr-3 checkbox"728                                            size="2rem"729                                          />730                                        ) : (731                                          <BsSquare732                                            size="1.65rem"733                                            style={{734                                              margin: '0 1.15rem 0 .2rem',735                                            }}736                                          />737                                        )}738                                      </div>739                                      <div className="d-inline-flex">740                                        {question.question}741                                      </div>742                                    </Accordion.Toggle>743                                    <Accordion.Collapse744                                      eventKey={`question:${area}:${questionsIndex.toString()}`}745                                    >746                                      <Card.Body className="pl-5">747                                        <ListGroup variant="flush">748                                          {(question.answersOrder || []).map(749                                            (answersIndex) => (750                                              <ListGroup.Item751                                                key={`answer:${area}:${questionsIndex.toString()}:${answersIndex.toString()}`}752                                                className={753                                                  answers[area][754                                                    questionsIndex755                                                  ] === answersIndex756                                                    ? 'selected'757                                                    : ''758                                                }759                                                onClick={() => {760                                                  answered(761                                                    area,762                                                    questionsIndex,763                                                    answersIndex764                                                  );765                                                  trackEvent(766                                                    'Answered question',767                                                    `${area}: [${questionsIndex.toString()}]${768                                                      question.question769                                                    }: [${answersIndex.toString()}]${770                                                      question.answers[771                                                        answersIndex772                                                      ]773                                                    }`774                                                  );775                                                }}776                                              >777                                                {question.answers[answersIndex]}778                                              </ListGroup.Item>779                                            )780                                          )}781                                        </ListGroup>782                                      </Card.Body>783                                    </Accordion.Collapse>784                                  </Card>785                                )786                              )}787                            </Accordion>788                          </Tab.Pane>789                        ))}790                      </Tab.Content>791                    </Col>792                  </Row>793                </Tab.Container>794                <Button795                  size="lg"796                  className="mt-5 mb-3 button-results d-block d-md-none"797                  block798                  disabled={!canViewChart()}799                  onClick={() => {800                    setShowChart(true);801                    trackEvent('Viewed results');802                  }}803                  variant="custom"804                >805                  VIEW RESULTS806                </Button>807                {!canViewChart() ? (808                  <small className="text-center d-block d-md-none mx-3">809                    Answer a minimum of 4 questions in each section to view810                    results.811                  </small>812                ) : null}813              </Col>814            </Row>815            {showCalculate ? (816              <div817                id="result-content"818                className="area-info d-flex align-items-start"819              >820                <Row className="justify-content-center w-100">821                  <Col md="10" lg="8" xl="6">822                    <div className="result-content border shadow text-center">823                      <h3 className="mb-4">Calculating Results</h3>824                      <Spinner825                        as="span"826                        animation="border"827                        size="lg"828                        role="status"829                        aria-hidden="true"830                      />831                    </div>832                  </Col>833                </Row>834              </div>835            ) : null}836          </>837        ) : (838          <div className="graph-wrapper">839            {viewResult ? (840              <div841                id="result-content"842                className="area-info d-flex align-items-start"843              >844                <Row className="justify-content-center">845                  <Col md="10" lg="9" xl="8" className="px-0 px-sm-3 text-left">846                    <div847                      className={`result-content border shadow ${viewResult}`}848                    >849                      <div>850                        <h3>851                          <strong>{viewResult}:</strong>{' '}852                          {getScoreLabel(scores[viewResult])}853                        </h3>854                        <button855                          type="button"856                          className="close"857                          onClick={() => {858                            setViewResult(null);859                            trackEvent('Closed results');860                          }}861                        >862                          <span aria-hidden="true">Ã</span>863                          <span className="sr-only">Close</span>864                        </button>865                      </div>866                      {867                        Recommendations[viewResult][868                          getScoreLabel(scores[viewResult])869                        ]870                      }871                    </div>872                  </Col>873                </Row>874              </div>875            ) : null}876            {showGetPdf ? (877              <div878                id="result-content"879                className="area-info d-flex align-items-start"880              >881                <Row className="justify-content-center w-100">882                  <Col md="10" lg="8" xl="6">883                    <div className="result-content border shadow text-center">884                      <button885                        type="button"886                        className="close"887                        style={{888                          position: 'absolute',889                          top: '-2rem',890                          right: '-1rem',891                        }}892                        onClick={() => {893                          setShowGetPdf(false);894                          trackEvent('Closed get PDF');895                        }}896                      >897                        <span aria-hidden="true">Ã</span>898                        <span className="sr-only">Close</span>899                      </button>900                      <h3 className="mb-4">Get Your Results in PDF</h3>901                      <Form.Control902                        type="text"903                        name="Name"904                        className="mb-3"905                        placeholder="Name"906                        ref={formName}907                        disabled={sendingPdf}908                      />909                      <Form.Control910                        type="text"911                        name="Email"912                        className="mb-3"913                        placeholder="Email"914                        ref={formEmail}915                        disabled={sendingPdf}916                      />917                      {showFormError ? (918                        <p className="text-danger my-3">919                          Please submit a valid email address.920                        </p>921                      ) : null}922                      <Button923                        size="lg"924                        className="button-getintouch mx-2 mx-auto"925                        onClick={async () => {926                          const name = formName.current.value;927                          const email = formEmail.current.value;928                          trackEvent('Request email PDF');929                          if (!validateEmail(email)) {930                            setShowFormError(true);931                          } else {932                            setShowFormError(false);933                            setSendingPdf(true);934                            await createPdf(935                              formType,936                              {937                                email,938                                name,939                              },940                              getContactClick(),941                              scores942                            );943                            if (typeof window !== 'undefined') {944                              window.setTimeout(() => {945                                setShowGetPdf(false);946                                setSendingPdf(false);947                              }, 200);948                            }949                          }950                        }}951                        disabled={sendingPdf}952                      >953                        {sendingPdf ? (954                          <Spinner955                            as="span"956                            animation="border"957                            size="lg"958                            role="status"959                            aria-hidden="true"960                          />961                        ) : (962                          'Submit'963                        )}964                      </Button>965                    </div>966                  </Col>967                </Row>968              </div>969            ) : null}970            <Row className="flex-shrink-1">971              <Col className="text-center">972                <h2>The results are in!</h2>973                <p>974                  Click each category to see how you scored. Ready to improve?975                </p>976                <Button977                  size="lg"978                  className="button-getintouch mx-2 mb-3"979                  onClick={() => {980                    setShowGetPdf(true);981                    trackEvent('Opened get PDF');982                  }}983                >984                  Get Results985                </Button>986                <Button987                  size="lg"988                  className="button-getintouch-outline mx-2 mb-3"989                  onClick={() => {990                    setShowChart(false);991                    trackEvent('Closed results');992                  }}993                >994                  Change my Answers995                </Button>996              </Col>997            </Row>998            <Row className="flex-grow-1 mt-3" style={{ minHeight: '500px' }}>999              <Col md="3" lg="2" className="d-md-flex pr-0 d-none border-right">1000                <Row className="flex-grow-1">1001                  <Col className="d-flex flex-column">1002                    <ul className="yAxis p-0 m-0 d-flex flex-column flex-grow-1 align-items-stretch">1003                      <li className="d-flex flex-grow-1 align-items-center">1004                        <small className="text-right pr-3">1005                          Highly Efficient, Digital, Agile, Integrated &1006                          Continual1007                        </small>1008                      </li>1009                      <li className="d-flex flex-grow-1 align-items-center">1010                        <small className="text-right pr-3">1011                          Effective, Accurate, Centralized, Adjustable &1012                          Periodic1013                        </small>1014                      </li>1015                      <li className="d-flex flex-grow-1 align-items-center">1016                        <small className="text-right pr-3">1017                          Manual, Burdensome, Occasional, Isolated &1018                          Document Centric1019                        </small>1020                      </li>1021                      <li className="d-flex flex-grow-1 align-items-center">1022                        <small className="text-right pr-3">1023                          Inefficient, Fragmented, Isolated, Inflexible &1024                          Chaotic1025                        </small>1026                      </li>1027                    </ul>1028                  </Col>1029                </Row>1030              </Col>1031              <Col1032                md="9"1033                lg="10"1034                className="graph d-flex flex-column pl-0 pr-0 pr-md-3"1035              >1036                <Row className="border-bottom flex-grow-1" noGutters>1037                  {Object.keys(Questions).map((area) => (1038                    <Col1039                      key={`bar:${area}`}1040                      className="graph-bar text-center align-items-end d-flex"1041                    >1042                      <div1043                        role="button"1044                        tabIndex="0"1045                        onClick={() => {1046                          setViewResult(area);1047                          window.setTimeout(() => {1048                            if (typeof document !== 'undefined') {1049                              document1050                                .getElementById('cs-widget-chart')1051                                .scrollIntoView({1052                                  behavior: 'smooth',1053                                  block: 'start',1054                                });1055                            }1056                          }, 250);1057                        }}1058                        onKeyPress={() => setViewResult(area)}1059                        className={`w-100 bar ${area} text-center text-white`}1060                        style={{ height: `${scores[area]}%` }}1061                      >1062                        <small className="d-block">1063                          <strong>{getScoreLabel(scores[area])}</strong>1064                        </small>1065                        <Button1066                          size="sm"1067                          variant="outline-light"1068                          className="my-3 more-info d-flex align-items-center mx-auto"1069                        >1070                          More Info1071                          <BsFillInfoCircleFill className="ml-2" />1072                        </Button>1073                        <div className="d-md-none">1074                          {getScoreLabel(scores[area]) === 'Optimized' ? (1075                            <small>1076                              Highly Efficient, Digital, Agile, Integrated &1077                              Continual1078                            </small>1079                          ) : null}1080                          {getScoreLabel(scores[area]) === 'Managed' ? (1081                            <small>1082                              Effective, Accurate, Centralized, Adjustable &1083                              Periodic1084                            </small>1085                          ) : null}1086                          {getScoreLabel(scores[area]) === 'Basic' ? (1087                            <small>1088                              Manual, Burdensome, Occasional, Isolated &1089                              Document Centric1090                            </small>1091                          ) : null}1092                          {getScoreLabel(scores[area]) === 'Adhoc' ? (1093                            <small>1094                              Inefficient, Fragmented, Isolated, Inflexible1095                              & Chaotic1096                            </small>1097                          ) : null}1098                        </div>1099                      </div>1100                    </Col>1101                  ))}1102                </Row>1103              </Col>1104            </Row>1105            <Row className="flex-shrink-1">1106              <Col md="3" lg="2" className="d-block d-md-flex" />1107              <Col md="9" lg="10" className="graph pl-0  pr-0 pr-md-3">1108                <Row noGutters>1109                  {Object.keys(Questions).map((area) => (1110                    <Col1111                      key={`bar:${area}`}1112                      className="graph-bar bar-title text-center mt-2 pr-0"1113                    >1114                      <small>{area}</small>1115                    </Col>1116                  ))}1117                </Row>1118              </Col>1119            </Row>1120          </div>1121        )}1122      </div>1123    </>1124  );1125}...createpdf_worker.js
Source:createpdf_worker.js  
...113        switch(method){114            case "sendImg": addImgObject(eventData); return createResponse[method](); break;115            case "getParseHtmlPromise": return runConversion(eventData); break;116            case "checkProgress": return createResponse[method](); break;117            case "exportPdf": return createResponse[method](returnPdf()); break;118            default: return createResponse.unknown(method); break;119        }120    };121    return action;
...effective.js
Source:effective.js  
1import Effective from 'server/api/maya/effective/effective.js'2import Protos from 'common/protos'3import co from 'co'4describe('[unit] Effective api & test fetchList function', function() {5  let parameters = this6  const effectiveFunc = new Effective()7  const returnObject = {8    year: [],9  }10  const models = {11    getList: function* getList() {12      return returnObject13    },14  }15  it('it should be return object', async () => {16    let tempParamet = {17      ...parameters,18      'params':{},19      models,20    }21    co(effectiveFunc.fetchList.apply(tempParamet))22    .then(() => {23      const expectBuffer = Protos.EffectiveList.response.encode(returnObject).toBuffer()24      expect(tempParamet.body).toEqual(expectBuffer)25    })26  })27  it('should import Effective model when this.model does not exist.', async () => {28    let tempParamet = {29      ...parameters,30      'params':{},31    }32    const genThis = function () {33      return tempParamet34    }35    co(effectiveFunc.fetchList.apply(genThis())).then(successHandler, errorHnadler)36  })37})38describe('[unit] Effective api & test fetchPDF function', function() {39  let parameters = this40  const effectiveFunc = new Effective()41  const models = {42    getPDF: function* getPDF(year) {43      return 'returnPDF'44    },45  }46  it('it should be return object', async () => {47    let tempParamet = {48      ...parameters,49      'params': {50        'year': '2017',51        'lang': 'en',52      },53      models,54      attachment: function() {55        return true56      },57    }58    co(effectiveFunc.fetchPDF.apply(tempParamet))59    .then(() => {60      expect(tempParamet.body).toEqual('returnPDF')61    })62  })63  it('input number, it should be return object', async () => {64    let tempParamet = {65      ...parameters,66      'params': {67        'year': '2017',68        'lang': 'en',69      },70      models,71      attachment: function() {72        return true73      },74    }75    co(effectiveFunc.fetchPDF.apply(tempParamet))76    .then(() => {77      expect(tempParamet.body).toEqual('returnPDF')78    })79  })80  it('should import Accuracy model when this.model does not exist.', async () => {81    let tempParamet = {82      ...parameters,83      'params': {84        'year': '2017',85        'lang': 'en',86      },87      attachment: function() {88        return true89      },90    }91    const genThis = function () {92      return tempParamet93    }94    co(effectiveFunc.fetchPDF.apply(genThis())).then(successHandler, errorHnadler)95  })96})97const successHandler = function() {98}99const errorHnadler = function(err) {100  console.warn(err)...Using AI Code Generation
1var Chromeless = require('chromeless').Chromeless;2async function run() {3  const chromeless = new Chromeless()4    .type('chromeless', 'input[name="q"]')5    .press(13)6    .wait('#resultStats')7    .returnPdf()8    .end()9  await chromeless.end()10}11run().catch(console.error.bind(console))12The .goto() method takes an optional second parameter which is an object with the following properties:13waitUntil: (optional) string or array of strings, can be one of:14The .click() method takes an optional second parameter which is an object with the following properties:15The .type() method takes an optional second parameter which is an object with the following properties:16The .press() method takes an optional second parameter which is an object with the following properties:17The .wait() method takes an optional second parameter which is an object with the following properties:18timeout: (optional) number, maximum time to wait for in milliseconds. Defaults to 30000Using AI Code Generation
1const Chromeless = require('chromeless').Chromeless;2const chromeless = new Chromeless();3async function run() {4    .returnPdf()5  await chromeless.end()6}7run().catch(console.error.bind(console))8const Chromeless = require('chromeless').Chromeless;9const chromeless = new Chromeless();10async function run() {11    .returnPdf()12  await chromeless.end()13}14run().catch(console.error.bind(console))15const Chromeless = require('chromeless').Chromeless;16const chromeless = new Chromeless();17async function run() {18    .returnPdf()19  await chromeless.end()20}21run().catch(console.error.bind(console))22const Chromeless = require('chromeless').Chromeless;23const chromeless = new Chromeless();24async function run() {25    .returnPdf()26  await chromeless.end()27}28run().catch(console.error.bind(console))29const Chromeless = require('chromeless').Chromeless;30const chromeless = new Chromeless();31async function run() {32    .returnPdf()Using AI Code Generation
1const chromeless = new Chromeless()2  .returnPdf()3await chromeless.end()4const chromeless = new Chromeless()5  .returnPdf({landscape: true})6await chromeless.end()7const chromeless = new Chromeless()8  .returnPdf({landscape: true, displayHeaderFooter: true, headerTemplate: '<div>Header</div>'})9await chromeless.end()10const chromeless = new Chromeless()11  .returnPdf({landscape: true, displayHeaderFooter: true, headerTemplate: '<div>Header</div>', footerTemplate: '<div>Footer</div>', printBackground: true})12await chromeless.end()13const chromeless = new Chromeless()14  .returnPdf({landscape: true, displayHeaderFooter: true, headerTemplate: '<div>Header</div>', footerTemplate: '<div>Footer</div>', printBackground: true, preferCSSPageSize: true})15await chromeless.end()16const chromeless = new Chromeless()17  .returnPdf({landscape:Using AI Code Generation
1const chromeless = new Chromeless({ remote: true })2  .returnPdf()3await chromeless.end()4### `new Chromeless(options)`5* `remote` (boolean, default: `false`) - whether to run Chromeless remotely or locally6* `implicitWait` (boolean, default: `true`) - whether to wait for elements to appear before executing commands7* `implicitWaitTimeout` (number, default: `5000`) - how long to wait for elements to appear before throwing an error8* `scrollBeforeClick` (boolean, default: `true`) - whether to scroll to an element before clicking it9* `scrollBeforeHover` (boolean, default: `true`) - whether to scroll to an element before hovering over it10* `scrollBeforeScreenshot` (boolean, default: `true`) - whether to scroll to an element before taking a screenshot11* `scrollBeforeWaitForElement` (boolean, default: `true`) - whether to scroll to an element before waiting for it to appear12* `scrollToBottomBeforeWaitForElement` (boolean, default: `true`) - whether to scroll to the bottom of the page before waiting for an element to appear13* `waitTimeout` (number, default: `10000`) - how long to wait for an element to appear before throwing an error14* `debug` (boolean, default: `false`) - whether to log debug information to the console15* `cws` (boolean, default: `false`) - whether to use Chrome Web Store version of Chrome16* `chromeFlags` (array, default: `['--disable-gpu', '--remote-debugging-port=9222']`) - additional flags to pass to Chrome17* `launchChromeFlags` (array, default: `['--disable-gpu', '--remote-debugging-port=9222', '--window-size=412,732']`) - additional flags to pass to Chrome when launching it18* `launchConfig` (object, default: `{dumpio: false, pipe: false, logLevel: 'Using AI Code Generation
1const chromeless = new Chromeless();2  .returnPdf()3  .end()4fs.writeFileSync('google.pdf', pdf)5const chromeless = new Chromeless();6  .returnPdf()7  .end()8fs.writeFileSync('google.pdf', pdf)9const chromeless = new Chromeless();10  .returnPdf()11  .end()12fs.writeFileSync('google.pdf', pdf)13const chromeless = new Chromeless();14  .returnPdf()15  .end()16fs.writeFileSync('google.pdf', pdf)17const chromeless = new Chromeless();18  .returnPdf()19  .end()20fs.writeFileSync('google.pdf', pdf)21const chromeless = new Chromeless();22  .returnPdf()23  .end()24fs.writeFileSync('google.pdf', pdf)Using AI Code Generation
1const Chromeless = require('chromeless').Chromeless;2const chromeless = new Chromeless();3  .returnPdf()4  .then(pdf => {5  })6  .catch(console.error.bind(console))7  .then(() => chromeless.end());8const Chromeless = require('chromeless').Chromeless;9const chromeless = new Chromeless();10  .returnPdf({landscape: true})11  .then(pdf => {12  })13  .catch(console.error.bind(console))14  .then(() => chromeless.end());15const Chromeless = require('chromeless').Chromeless;16const chromeless = new Chromeless();17  .returnPdf({landscape: true, displayHeaderFooter: true, printBackground: true})18  .then(pdf => {19  })20  .catch(console.error.bind(console))21  .then(() => chromeless.end());22const Chromeless = require('chromeless').Chromeless;23const chromeless = new Chromeless();24  .returnPdf({landscape: true, displayHeaderFooter: true, printBackground: true, headerTemplate: 'headerTemplate'})25  .then(pdf => {26  })27  .catch(console.error.bindUsing AI Code Generation
1const Chromeless = require('chromeless').Chromeless2const fs = require('fs')3const chromeless = new Chromeless()4  .type('chromeless', 'input[name="q"]')5  .press(13)6  .wait('#resultStats')7  .returnPdf()8  .then(pdf => {9    fs.writeFileSync('google.pdf', pdf, 'utf8')10  })11  .catch(console.error)12  .then(() => chromeless.end())13{14  "scripts": {15  },16  "dependencies": {17  }18}Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
