Best JavaScript code snippet using chromeless
eventrouter.js
Source:eventrouter.js  
1/*2 * Copyright 2019-present Open Networking Foundation3 * Licensed under the Apache License, Version 2.0 (the "License");4 * you may not use this file except in compliance with the License.5 * You may obtain a copy of the License at6 * http://www.apache.org/licenses/LICENSE-2.07 * Unless required by applicable law or agreed to in writing, software8 * distributed under the License is distributed on an "AS IS" BASIS,9 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.10 * See the License for the specific language governing permissions and11 * limitations under the License.12 */13(function () {14    'use strict';15    const _ = require('lodash');16    const logger = require('../config/logger.js');17    const Client = require('../types/client.js');18    const WorkflowRun = require('../types/workflowrun.js');19    const ws_probe = require('./ws_probe.js');20    const ws_manager = require('./ws_manager.js');21    const ws_workflowrun = require('./ws_workflowrun.js');22    let allClients = {}; // has publishers and subscribers23    let probeClients = {}; // a subset of clients24    let workflowManagerClients = {}; // a subset of clients25    let workflowRunClients = {}; // a subset of clients26    //let io;27    // key: workflow id28    // value: Workflow instance29    let workflows = {};30    // key: workflow run id31    // value: WorkflowRun instance32    let workflowRuns = {};33    let serviceEvents = {34        GREETING: 'cord.workflow.ctlsvc.greeting'35    };36    setInterval(function () {37        let requests = [];38        _.forOwn(workflowRuns, (workflowRun, workflowRunId) => {39            let obj = {40                workflow_id: workflowRun.getWorkflowId(),41                workflow_run_id: workflowRunId42            };43            requests.push(obj);44        });45        checkWorkflowRunStatusBulk(requests);46    }, 5000);47    // add ws_probe events48    _.forOwn(ws_probe.serviceEvents, (wsServiceEvent, key) => {49        serviceEvents[key] = wsServiceEvent;50    });51    // add ws_manager events52    _.forOwn(ws_manager.serviceEvents, (wsServiceEvent, key) => {53        serviceEvents[key] = wsServiceEvent;54    });55    // add ws_workflowrun events56    _.forOwn(ws_workflowrun.serviceEvents, (wsServiceEvent, key) => {57        serviceEvents[key] = wsServiceEvent;58    });59    //const setIO = (ioInstance) => {60    //    io = ioInstance;61    //};62    const checkObject = (obj) => {63        return Object.prototype.toString.call(obj) === '[object Object]';64    };65    const destroy = () => {66        removeClients();67        clearWorkflowRuns();68        clearWorkflows();69    };70    const listWorkflows = () => {71        let workflowList = [];72        _.forOwn(workflows, (_workflow, workflowId) => {73            workflowList.push(workflowId);74        });75        return workflowList;76    };77    const checkWorkflow = (workflowId) => {78        if(workflowId in workflows) {79            return true;80        }81        return false;82    };83    const addWorkflow = (workflow) => {84        if(workflow.getId() in workflows) {85            logger.log('error', `there exists a workflow with the same id - ${workflow.getId()}`);86            return false;87        }88        let workflowId = workflow.getId();89        workflows[workflowId] = workflow;90        return true;91    };92    const getWorkflow = (workflowId) => {93        if(workflowId in workflows) {94            logger.log('warn', `cannot find a workflow with id - ${workflowId}`);95            return null;96        }97        return workflows[workflowId];98    };99    const clearWorkflows = () => {100        _.forOwn(workflows, (_workflow, workflowId) => {101            delete workflows[workflowId];102        });103    };104    const listWorkflowRuns = () => {105        let workflowRunList = [];106        _.forOwn(workflowRuns, (_workflowRun, workflowRunId) => {107            workflowRunList.push(workflowRunId);108        });109        return workflowRunList;110    };111    const checkWorkflowRun = (workflowRunId) => {112        if(workflowRunId in workflowRuns) {113            return true;114        }115        return false;116    };117    const addWorkflowRun = (workflowRun) => {118        let workflowId = workflowRun.getWorkflowId();119        let workflowRunId = workflowRun.getId();120        if(workflowRunId in workflowRuns) {121            logger.log('warn', `there exists a workflow run with the same id - ${workflowRunId}`);122            return false;123        }124        if(!(workflowId in workflows)) {125            logger.log('warn', `cannot find a workflow with id - ${workflowId}`);126            return false;127        }128        workflowRuns[workflowRunId] = workflowRun;129        return true;130    };131    const getWorkflowRun = (workflowRunId) => {132        if(workflowRunId in workflowRuns) {133            logger.log('warn', `cannot find a workflow run with id - ${workflowRunId}`);134            return null;135        }136        return workflowRuns[workflowRunId];137    };138    const clearWorkflowRuns = () => {139        _.forOwn(workflowRuns, (_workflowRun, workflowRunId) => {140            delete workflowRuns[workflowRunId];141        });142    };143    const setWorkflowRunKickstarted = (workflowRunId) => {144        if(!(workflowRunId in workflowRuns)) {145            logger.log('warn', `cannot find a workflow run with the id - ${workflowRunId}`);146            return false;147        }148        let workflowRun = workflowRuns[workflowRunId];149        workflowRun.setKickstarted();150        return true;151    };152    const setWorkflowRunStatus = (workflowRunId, status) => {153        if(!(workflowRunId in workflowRuns)) {154            logger.log('warn', `cannot find a workflow run with the id - ${workflowRunId}`);155            return false;156        }157        if(status === 'success' || status === 'failed' || status === 'end') {158            removeWorkflowRun(workflowRunId);159        }160        return true;161    };162    const kickstart = (workflowId, workflowRunId) => {163        if(!(workflowId in workflows)) {164            logger.log('warn', `cannot find a workflow with the id - ${workflowId}`);165            return false;166        }167        if(!(workflowRunId in workflowRuns)) {168            logger.log('warn', `cannot find a workflow run with the id - ${workflowRunId}`);169            return false;170        }171        ws_manager.kickstartWorkflow(workflowId, workflowRunId);172        return true;173    };174    /*175    const checkWorkflowRunStatus = (workflowId, workflowRunId) => {176        if(!(workflowId in workflows)) {177            logger.log('warn', `cannot find a workflow with the id - ${workflowId}`);178            return false;179        }180        if(!(workflowRunId in workflowRuns)) {181            logger.log('warn', `cannot find a workflow run with the id - ${workflowRunId}`);182            return false;183        }184        ws_manager.checkWorkflowRunStatus(workflowId, workflowRunId);185        return true;186    };187    */188    const checkWorkflowRunStatusBulk = (requests) => {189        if(requests) {190            ws_manager.checkWorkflowRunStatusBulk(requests);191            return true;192        }193        return false;194    };195    const removeWorkflow = (workflowId) => {196        if(!(workflowId in workflows)) {197            logger.log('warn', `cannot find a workflow with the id - ${workflowId}`);198            return false;199        }200        // check if there are workflow runs201        for(let key in workflowRuns) {202            if (!workflowRuns.hasOwnProperty(key)) {203                continue;204            }205            let workflowRun = workflowRuns[key];206            if(workflowRun.getWorkflowId() === workflowId) {207                logger.log('warn', `there exists a workflow run for a workflow id - ${workflowId}`);208                return false;209            }210        }211        // we don't use below code becuase it cannot properly stop and return value with 'return'212        // _.forOwn(workflowRuns, (workflowRun, _workflowRunId) => {213        //     if(workflowRun.getWorkflowId() === workflowId) {214        //         logger.log('warn', `there exists a workflow run for a workflow id - ${workflowId}`);215        //         return false;216        //     }217        // });218        delete workflows[workflowId];219        return true;220    };221    const removeWorkflowRun = (workflowRunId) => {222        if(!(workflowRunId in workflowRuns)) {223            logger.log('warn', `cannot find a workflow run with the id - ${workflowRunId}`);224            return false;225        }226        let workflowRun = workflowRuns[workflowRunId];227        delete workflowRuns[workflowRunId];228        workflowRun.setFinished();229        return true;230    };231    const emitEvent = (topic, message) => {232        logger.log('debug', `event is raised : topic ${topic}, message ${JSON.stringify(message)}`);233        let runningWorkflows = [];234        // route event to running instances235        _.forOwn(workflowRuns, (workflowRun, workflowRunId) => {236            let workflowId = workflowRun.getWorkflowId();237            let workflow = workflows[workflowId];238            if(workflow.isEventAcceptable(topic)) {239                logger.log('debug', `workflow ${workflowId} accept the event : topic ${topic}`);240                // event is acceped if event has241                // the same key field and its value as workflow_run242                if(workflowRun.isEventAcceptable(topic, message)) {243                    logger.log('debug', `workflow run ${workflowRunId} accept the event : \244                                topic ${topic}, message ${JSON.stringify(message)}`);245                    workflowRun.updateEventKeyFieldValueFromMessage(topic, message);246                    logger.log('debug', `event ${topic} is routed to workflow run ${workflowRunId}`);247                    workflowRun.enqueueEvent(topic, message);248                    // mark to not kickstart a new one249                    runningWorkflows.push(workflowId);250                }251                else {252                    logger.log('debug', `workflow run ${workflowRunId} reject the event : \253                                topic ${topic}, message ${JSON.stringify(message)}`);254                }255            }256        });257        // check if the event is a kickstart event258        _.forOwn(workflows, (workflow, workflowId) => {259            if(!runningWorkflows.includes(workflowId)) {260                if(workflow.isKickstartTopic(topic)) {261                    // we need to buffer the event until workflow run is brought up262                    let workflowRun = WorkflowRun.WorkflowRun.makeNewRun(workflow);263                    workflowRun.updateEventKeyFieldValueFromMessage(topic, message);264                    let workflowRunId = workflowRun.getId();265                    // register for management266                    workflowRuns[workflowRunId] = workflowRun;267                    // route event268                    logger.log('debug', `event ${topic} is routed to a new workflow run ${workflowRunId}`);269                    workflowRun.enqueueEvent(topic, message);270                    // KICKSTART!271                    kickstart(workflowId, workflowRunId);272                }273            }274        });275        return true;276    };277    const countQueuedEvents = (workflowRunId) => {278        // this counts queued events279        if(!(workflowRunId in workflowRuns)) {280            logger.log('warn', `workflow run ${workflowRunId} does not exist`);281            return null;282        }283        let workflowRun = workflowRuns[workflowRunId];284        return workflowRun.lengthEventQueue();285    };286    const fetchEvent = (workflowRunId, taskId, topic) => {287        // this returns an event or an empty obj when there is no message288        if(!(workflowRunId in workflowRuns)) {289            logger.log('warn', `workflow run ${workflowRunId} does not exist`);290            return null;291        }292        let workflowRun = workflowRuns[workflowRunId];293        let workflowId = workflowRun.getWorkflowId();294        if(!(workflowId in workflows)) {295            logger.log('warn', `workflow ${workflowId} does not exist`);296            return null;297        }298        let workflow = workflows[workflowId];299        let task = workflow.getTask(taskId);300        if(!task) {301            logger.log('warn', `workflow ${workflowId} does not have task ${taskId}`);302            return null;303        }304        logger.log('debug', `workflow run ${workflowRunId}, task ${taskId} fetches an event`);305        let event = workflowRun.dequeueEventByTopic(topic);306        if(event) {307            return event;308        }309        else {310            return {};311        }312    };313    const addClient = (c) => {314        let clientId = c.getId();315        let socket = c.getSocket();316        // check id that client is already there317        if(clientId in allClients) {318            logger.log('warn', `there exists a client with the same id - ${clientId}`);319            return false;320        }321        if(c.getType() === Client.Type.PROBE) {322            // probe323            // probe protocol:324            // REQ:325            //      topic: operation326            //      message: {327            //          req_id: <req_id>,328            //          topic: <topic>,329            //          message: <data>330            //      }331            // RES:332            //      topic: topic sent333            //      message: {334            //          req_id: <req_id>,335            //          error: <true/false>,336            //          result: <true/false>,337            //          message: <error message>338            //      }339            allClients[clientId] = c;340            probeClients[clientId] = c;341            // attach probe operations342            let router = ws_probe.getRouter();343            _.forOwn(router, (routerElem, _key) => {344                socket.on(routerElem.topic, (msg) => {345                    logger.log('debug', `received a probe event ${routerElem.topic} - ${JSON.stringify(msg)}`);346                    // handle a common parameter - req_id347                    // when we get req_id, return the same req_id in response.348                    // this is to help identify a request from a response at client-side349                    let req_id = 101010; // default number, signiture350                    if(msg && checkObject(msg)) {351                        if('req_id' in msg) {352                            req_id = msg.req_id;353                        }354                    }355                    routerElem.handler(routerElem.topic, msg || {}, (err, result) => {356                        if(err) {357                            logger.log('warn', `unable to handle a message - ${err}`);358                            socket.emit(routerElem.topic, {359                                req_id: req_id,360                                error: true,361                                result: result,362                                message: err363                            });364                            return;365                        }366                        // we return result367                        if(routerElem.return === undefined || routerElem.return) {368                            socket.emit(routerElem.topic, {369                                req_id: req_id,370                                error: false,371                                result: result372                            });373                        }374                    });375                });376            });377            return true;378        }379        else if(c.getType() === Client.Type.WORKFLOW_MANAGER) {380            // manager381            // manager protocol:382            // REQ:383            //      topic: operation384            //      message: {385            //          req_id: <req_id>,386            //          <data>...387            //      }388            // RES:389            //      topic: topic sent390            //      message: {391            //          req_id: <req_id>,392            //          error: <true/false>,393            //          result: <true/false>,394            //          message: <error message>395            //      }396            allClients[clientId] = c;397            workflowManagerClients[clientId] = c;398            // attach manager operations399            let router = ws_manager.getRouter();400            _.forOwn(router, (routerElem, _key) => {401                socket.on(routerElem.topic, (msg) => {402                    logger.log('debug', `received a manager event ${routerElem.topic} - ${JSON.stringify(msg)}`);403                    // handle a common parameter - req_id404                    // when we get req_id, return the same req_id in response.405                    // this is to help identify a request from a response at client-side406                    let req_id = 101010; // default number, signiture407                    if(msg && checkObject(msg)) {408                        if('req_id' in msg) {409                            req_id = msg.req_id;410                        }411                    }412                    routerElem.handler(routerElem.topic, msg || {}, (err, result) => {413                        if(err) {414                            logger.log('warn', `unable to handle a message - ${err}`);415                            socket.emit(routerElem.topic, {416                                req_id: req_id,417                                error: true,418                                result: result,419                                message: err420                            });421                            return;422                        }423                        // we return result424                        if(routerElem.return === undefined || routerElem.return) {425                            socket.emit(routerElem.topic, {426                                req_id: req_id,427                                error: false,428                                result: result429                            });430                        }431                    });432                });433            });434            return true;435        }436        else if(c.getType() === Client.Type.WORKFLOW_RUN) {437            // workflow run438            // workflow run protocol:439            // REQ:440            //      topic: operation441            //      message: {442            //          req_id: <req_id>,443            //          <data>...444            //      }445            // RES:446            //      topic: topic sent447            //      message: {448            //          req_id: <req_id>,449            //          error: <true/false>,450            //          result: <true/false>,451            //          message: <error message>452            //      }453            // map to WorkflowRun instance454            let workflowId = c.getWorkflowId();455            let workflowRunId = c.getWorkflowRunId();456            let workflowRun;457            if(!(workflowId in workflows)) {458                logger.log('warn', `cannot find a workflow ${workflowId}`);459                return false;460            }461            // register client to workflow run462            if(!(workflowRunId in workflowRuns)) {463                // workflow run not exist yet464                logger.log('warn', `cannot find a workflow run ${workflowRunId}`);465                return false;466            }467            //let workflow = workflows[workflowId];468            allClients[clientId] = c;469            workflowRunClients[clientId] = c;470            // update471            workflowRun = workflowRuns[workflowRunId];472            workflowRun.addClientId(clientId);473            // attach workflow run operations474            let router = ws_workflowrun.getRouter();475            _.forOwn(router, (routerElem, _key) => {476                socket.on(routerElem.topic, (msg) => {477                    logger.log('debug', `received a workflow run event ${routerElem.topic} - ${JSON.stringify(msg)}`);478                    // handle a common parameter - req_id479                    // when we get req_id, return the same req_id in response.480                    // this is to help identify a request from a response at client-side481                    let req_id = 101010; // default number, signiture482                    if(msg && checkObject(msg)) {483                        if('req_id' in msg) {484                            req_id = msg.req_id;485                        }486                    }487                    routerElem.handler(routerElem.topic, msg || {}, (err, result) => {488                        if(err) {489                            logger.log('warn', `unable to handle a message - ${err}`);490                            socket.emit(routerElem.topic, {491                                req_id: req_id,492                                error: true,493                                result: false,494                                message: err495                            });496                            return;497                        }498                        // we return result499                        if(routerElem.return === undefined || routerElem.return) {500                            socket.emit(routerElem.topic, {501                                req_id: req_id,502                                error: false,503                                result: result504                            });505                        }506                    });507                });508            });509            return true;510        }511        return false;512    };513    const removeClient = (id) => {514        if(id in allClients) {515            let removedClient = allClients[id];516            delete allClients[id];517            let type = removedClient.getType();518            if(type === Client.Type.PROBE) {519                delete probeClients[id];520            }521            else if(type === Client.Type.WORKFLOW_MANAGER) {522                delete workflowManagerClients[id];523            }524            else if(type === Client.Type.WORKFLOW_RUN) {525                delete workflowRunClients[id];526                let workflowRunId = removedClient.getWorkflowRunId();527                let workflowRun = workflowRuns[workflowRunId];528                if(workflowRun) {529                    workflowRun.removeClientId(id);530                    //TODO531                    // WorkflowRun can have no clients between tasks532                    // So we should not remove the run until the workflow run finishes533                }534            }535        }536    };537    const removeClients = () => {538        let probeClients = {};539        _.forOwn(probeClients, (_probeClient, clientId) => {540            delete probeClients[clientId];541        });542        _.forOwn(workflowManagerClients, (_workflowManagerClient, clientId) => {543            delete workflowManagerClients[clientId];544        });545        _.forOwn(workflowRunClients, (_workflowRunClients, clientId) => {546            delete workflowRunClients[clientId];547        });548        _.forOwn(allClients, (client, clientId) => {549            client.getSocket().disconnect(true);550            delete allClients[clientId];551        });552    }553    module.exports = {554        serviceEvents: serviceEvents,555        destroy: destroy,556        getClients: () => { return allClients; },557        getProbeClients: () => { return probeClients; },558        getWorkflowManagerClients: () => { return workflowManagerClients; },559        getWorkflowRunClients: () => { return workflowRunClients; },560        clientType: Client.Type,561        //setIO: setIO,562        emitEvent: emitEvent,563        countQueuedEvents: countQueuedEvents,564        fetchEvent: fetchEvent,565        addClient: addClient,566        removeClient: removeClient,567        removeClients: removeClients,568        addWorkflow: addWorkflow,569        getWorkflow: getWorkflow,570        listWorkflows: listWorkflows,571        checkWorkflow: checkWorkflow,572        removeWorkflow: removeWorkflow,573        clearWorkflows: clearWorkflows,574        addWorkflowRun: addWorkflowRun,575        getWorkflowRun: getWorkflowRun,576        listWorkflowRuns: listWorkflowRuns,577        checkWorkflowRun: checkWorkflowRun,578        removeWorkflowRun: removeWorkflowRun,579        clearWorkflowRuns: clearWorkflowRuns,580        setWorkflowRunKickstarted: setWorkflowRunKickstarted,581        setWorkflowRunStatus: setWorkflowRunStatus582    };...hook.js
Source:hook.js  
...23}24/**25 * Call every function in the array `hook' with the remaining26 * arguments of this function.  Note: This should only be used by27 * define_hook and friends to define hook.run(...) functions.  Hooks28 * should always be run by calling hook.run(...).29 */30function run_hooks (hook, args) {31    if (hook == null)32        return;33    for (let i = 0, hlen = hook.length; i < hlen; ++i)34        hook[i].apply(null, Array.prototype.slice.call(args));35}36function run_hooks_until_success (hook, args) {37    if (hook == null)38        return false;39    var result;40    for (let i = 0, hlen = hook.length; i < hlen; ++i)41        if ((result = hook[i].apply(null, Array.prototype.slice.call(args))))42            return result;...course_card_model.js
Source:course_card_model.js  
1/* globals gettext */2import Backbone from 'backbone';3import DateUtils from 'edx-ui-toolkit/js/utils/date-utils';4import StringUtils from 'edx-ui-toolkit/js/utils/string-utils';5/**6 * Model for Course Programs.7 */8class CourseCardModel extends Backbone.Model {9  initialize(data) {10    if (data) {11      this.context = data;12      this.setActiveCourseRun(this.getCourseRun(data), data.user_preferences);13    }14  }15  getCourseRun(course) {16    const enrolledCourseRun = course.course_runs.find(run => run.is_enrolled);17    const openEnrollmentCourseRuns = this.getEnrollableCourseRuns();18    let desiredCourseRun;19    // If the learner has an existing, unexpired enrollment,20    // use it to populate the model.21    if (enrolledCourseRun && !course.expired) {22      desiredCourseRun = enrolledCourseRun;23    } else if (openEnrollmentCourseRuns.length > 0) {24      if (openEnrollmentCourseRuns.length === 1) {25        desiredCourseRun = openEnrollmentCourseRuns[0];26      } else {27        desiredCourseRun = CourseCardModel.getUnselectedCourseRun(openEnrollmentCourseRuns);28      }29    } else {30      desiredCourseRun = CourseCardModel.getUnselectedCourseRun(course.course_runs);31    }32    return desiredCourseRun;33  }34  getCourseRunWithHighestGrade(grades) {35    const allEnrolledCourseRuns = this.context.course_runs.filter(run => run.is_enrolled);36    if (allEnrolledCourseRuns.length <= 1) {37      return null;38    }39    allEnrolledCourseRuns.sort((a, b) => (grades[a.key] || 0) - (grades[b.key] || 0));40    return allEnrolledCourseRuns[allEnrolledCourseRuns.length - 1];41  }42  updateCourseRunWithHighestGrade(grades) {43    const courseRunWithHighestGrade = this.getCourseRunWithHighestGrade(grades);44    if (courseRunWithHighestGrade) {45      this.setActiveCourseRun(courseRunWithHighestGrade, this.context.user_preferences);46    }47  }48  isEnrolledInSession() {49    // Returns true if the user is currently enrolled in a session of the course50    return this.context.course_runs.find(run => run.is_enrolled) !== undefined;51  }52  static getUnselectedCourseRun(courseRuns) {53    const unselectedRun = {};54    if (courseRuns && courseRuns.length > 0) {55      const courseRun = courseRuns[0];56      $.extend(unselectedRun, {57        marketing_url: courseRun.marketing_url,58        is_enrollment_open: courseRun.is_enrollment_open,59        key: courseRun.key || '',60        is_mobile_only: courseRun.is_mobile_only || false,61      });62    }63    return unselectedRun;64  }65  getEnrollableCourseRuns() {66    const rawCourseRuns = this.context.course_runs.filter(run => (67      run.is_enrollment_open &&68      !run.is_enrolled &&69      !run.is_course_ended &&70      run.status === 'published'71    ));72    // Deep copy to avoid mutating this.context.73    const enrollableCourseRuns = $.extend(true, [], rawCourseRuns);74    // These are raw course runs from the server. The start75    // dates are ISO-8601 formatted strings that need to be76    // prepped for display.77    enrollableCourseRuns.forEach((courseRun) => {78      Object.assign(courseRun, {79        start_date: CourseCardModel.formatDate(courseRun.start),80        end_date: CourseCardModel.formatDate(courseRun.end),81        // This is used to render the date when selecting a course run to enroll in82        dateString: this.formatDateString(courseRun),83      });84    });85    return enrollableCourseRuns;86  }87  getUpcomingCourseRuns() {88    return this.context.course_runs.filter(run => (89      !run.is_enrollment_open &&90      !run.is_enrolled &&91      !run.is_course_ended &&92      run.status === 'published'93    ));94  }95  static formatDate(date, userPreferences) {96    let userTimezone = '';97    let userLanguage = '';98    if (userPreferences !== undefined) {99      userTimezone = userPreferences.time_zone;100      userLanguage = userPreferences['pref-lang'];101    }102    const context = {103      datetime: date,104      timezone: userTimezone,105      language: userLanguage,106      format: DateUtils.dateFormatEnum.shortDate,107    };108    return DateUtils.localize(context);109  }110  static getCertificatePriceString(run) {111    if ('seats' in run && run.seats.length) {112      // eslint-disable-next-line consistent-return113      const upgradeableSeats = run.seats.filter((seat) => {114        const upgradeableSeatTypes = ['verified', 'professional', 'no-id-professional', 'credit'];115        return upgradeableSeatTypes.indexOf(seat.type) >= 0;116      });117      if (upgradeableSeats.length > 0) {118        const upgradeableSeat = upgradeableSeats[0];119        if (upgradeableSeat) {120          const currency = upgradeableSeat.currency;121          if (currency === 'USD') {122            return `$${upgradeableSeat.price}`;123          }124          return `${upgradeableSeat.price} ${currency}`;125        }126      }127    }128    return null;129  }130  formatDateString(run) {131    const pacingType = run.pacing_type;132    let dateString;133    const start = CourseCardModel.valueIsDefined(run.start_date) ?134      run.advertised_start || run.start_date :135      this.get('start_date');136    const end = CourseCardModel.valueIsDefined(run.end_date) ? run.end_date : this.get('end_date');137    const now = new Date();138    const startDate = new Date(start);139    const endDate = new Date(end);140    if (pacingType === 'self_paced') {141      if (start) {142        dateString = startDate > now ?143          StringUtils.interpolate(gettext('(Self-paced) Starts {start}'), { start }) :144          StringUtils.interpolate(gettext('(Self-paced) Started {start}'), { start });145      } else if (end && endDate > now) {146        dateString = StringUtils.interpolate(gettext('(Self-paced) Ends {end}'), { end });147      } else if (end && endDate < now) {148        dateString = StringUtils.interpolate(gettext('(Self-paced) Ended {end}'), { end });149      }150    } else if (start && end) {151      dateString = `${start} - ${end}`;152    } else if (start) {153      dateString = startDate > now ?154                                StringUtils.interpolate(gettext('Starts {start}'), { start }) :155                                StringUtils.interpolate(gettext('Started {start}'), { start });156    } else if (end) {157      dateString = StringUtils.interpolate(gettext('Ends {end}'), { end });158    }159    return dateString;160  }161  static valueIsDefined(val) {162    return !([undefined, 'None', null].indexOf(val) >= 0);163  }164  setActiveCourseRun(courseRun, userPreferences) {165    let startDateString;166    let courseTitleLink = '';167    const isEnrolled = this.isEnrolledInSession() && courseRun.key;168    if (courseRun) {169      if (CourseCardModel.valueIsDefined(courseRun.advertised_start)) {170        startDateString = courseRun.advertised_start;171      } else {172        startDateString = CourseCardModel.formatDate(courseRun.start, userPreferences);173      }174      if (isEnrolled && courseRun.course_url) {175        courseTitleLink = courseRun.course_url;176      } else if (!isEnrolled && courseRun.marketing_url) {177        courseTitleLink = CourseCardModel.updateMarketingUrl(courseRun);178      }179      this.set({180        certificate_url: courseRun.certificate_url,181        course_run_key: courseRun.key || '',182        course_url: courseRun.course_url || '',183        title: this.context.title,184        end_date: CourseCardModel.formatDate(courseRun.end, userPreferences),185        enrollable_course_runs: this.getEnrollableCourseRuns(),186        is_course_ended: courseRun.is_course_ended,187        is_enrolled: isEnrolled,188        is_enrollment_open: courseRun.is_enrollment_open,189        course_key: this.context.key,190        user_entitlement: this.context.user_entitlement,191        is_unfulfilled_entitlement: this.context.user_entitlement && !isEnrolled,192        marketing_url: courseRun.marketing_url,193        mode_slug: courseRun.type,194        start_date: startDateString,195        upcoming_course_runs: this.getUpcomingCourseRuns(),196        upgrade_url: courseRun.upgrade_url,197        price: CourseCardModel.getCertificatePriceString(courseRun),198        course_title_link: courseTitleLink,199        is_mobile_only: courseRun.is_mobile_only || false,200      });201      // This is used to render the date for completed and in progress courses202      this.set({ dateString: this.formatDateString(courseRun) });203    }204  }205  setUnselected() {206    // Called to reset the model back to the unselected state.207    const unselectedCourseRun = CourseCardModel.getUnselectedCourseRun(this.get('enrollable_course_runs'));208    this.setActiveCourseRun(unselectedCourseRun);209  }210  updateCourseRun(courseRunKey) {211    const selectedCourseRun = this.get('course_runs').find(run => run.key === courseRunKey);212    if (selectedCourseRun) {213      // Update the current context to set the course run to the enrolled state214      this.context.course_runs.forEach((run) => {215        Object.assign(run, {216          is_enrolled: run.is_enrolled || run.key === selectedCourseRun.key,217        });218      });219      this.setActiveCourseRun(selectedCourseRun);220    }221  }222  // update marketing url for deep linking if is_mobile_only true223  static updateMarketingUrl(courseRun) {224    if (courseRun.is_mobile_only === true) {225      const marketingUrl = courseRun.marketing_url;226      let href = marketingUrl;227      if (marketingUrl.indexOf('course_info?path_id') < 0) {228        const start = marketingUrl.indexOf('course/');229        let path;230        if (start > -1) {231          path = marketingUrl.substr(start);232        }233        href = `edxapp://course_info?path_id=${path}`;234      }235      return href;236    }237    return courseRun.marketing_url;238  }239}...course_card_model.cfeeb788acc3.js
Source:course_card_model.cfeeb788acc3.js  
1/* globals gettext */2import Backbone from 'backbone';3import DateUtils from 'edx-ui-toolkit/js/utils/date-utils';4import StringUtils from 'edx-ui-toolkit/js/utils/string-utils';5/**6 * Model for Course Programs.7 */8class CourseCardModel extends Backbone.Model {9  initialize(data) {10    if (data) {11      this.context = data;12      this.setActiveCourseRun(this.getCourseRun(data), data.user_preferences);13    }14  }15  getCourseRun(course) {16    const enrolledCourseRun = course.course_runs.find(run => run.is_enrolled);17    const openEnrollmentCourseRuns = this.getEnrollableCourseRuns();18    let desiredCourseRun;19    // If the learner has an existing, unexpired enrollment,20    // use it to populate the model.21    if (enrolledCourseRun && !course.expired) {22      desiredCourseRun = enrolledCourseRun;23    } else if (openEnrollmentCourseRuns.length > 0) {24      if (openEnrollmentCourseRuns.length === 1) {25        desiredCourseRun = openEnrollmentCourseRuns[0];26      } else {27        desiredCourseRun = CourseCardModel.getUnselectedCourseRun(openEnrollmentCourseRuns);28      }29    } else {30      desiredCourseRun = CourseCardModel.getUnselectedCourseRun(course.course_runs);31    }32    return desiredCourseRun;33  }34  getCourseRunWithHighestGrade(grades) {35    const allEnrolledCourseRuns = this.context.course_runs.filter(run => run.is_enrolled);36    if (allEnrolledCourseRuns.length <= 1) {37      return null;38    }39    allEnrolledCourseRuns.sort((a, b) => (grades[a.key] || 0) - (grades[b.key] || 0));40    return allEnrolledCourseRuns[allEnrolledCourseRuns.length - 1];41  }42  updateCourseRunWithHighestGrade(grades) {43    const courseRunWithHighestGrade = this.getCourseRunWithHighestGrade(grades);44    if (courseRunWithHighestGrade) {45      this.setActiveCourseRun(courseRunWithHighestGrade, this.context.user_preferences);46    }47  }48  isEnrolledInSession() {49    // Returns true if the user is currently enrolled in a session of the course50    return this.context.course_runs.find(run => run.is_enrolled) !== undefined;51  }52  static getUnselectedCourseRun(courseRuns) {53    const unselectedRun = {};54    if (courseRuns && courseRuns.length > 0) {55      const courseRun = courseRuns[0];56      $.extend(unselectedRun, {57        marketing_url: courseRun.marketing_url,58        is_enrollment_open: courseRun.is_enrollment_open,59        key: courseRun.key || '',60        is_mobile_only: courseRun.is_mobile_only || false,61      });62    }63    return unselectedRun;64  }65  getEnrollableCourseRuns() {66    const rawCourseRuns = this.context.course_runs.filter(run => (67      run.is_enrollment_open &&68      !run.is_enrolled &&69      !run.is_course_ended &&70      run.status === 'published'71    ));72    // Deep copy to avoid mutating this.context.73    const enrollableCourseRuns = $.extend(true, [], rawCourseRuns);74    // These are raw course runs from the server. The start75    // dates are ISO-8601 formatted strings that need to be76    // prepped for display.77    enrollableCourseRuns.forEach((courseRun) => {78      Object.assign(courseRun, {79        start_date: CourseCardModel.formatDate(courseRun.start),80        end_date: CourseCardModel.formatDate(courseRun.end),81        // This is used to render the date when selecting a course run to enroll in82        dateString: this.formatDateString(courseRun),83      });84    });85    return enrollableCourseRuns;86  }87  getUpcomingCourseRuns() {88    return this.context.course_runs.filter(run => (89      !run.is_enrollment_open &&90      !run.is_enrolled &&91      !run.is_course_ended &&92      run.status === 'published'93    ));94  }95  static formatDate(date, userPreferences) {96    let userTimezone = '';97    let userLanguage = '';98    if (userPreferences !== undefined) {99      userTimezone = userPreferences.time_zone;100      userLanguage = userPreferences['pref-lang'];101    }102    const context = {103      datetime: date,104      timezone: userTimezone,105      language: userLanguage,106      format: DateUtils.dateFormatEnum.shortDate,107    };108    return DateUtils.localize(context);109  }110  static getCertificatePriceString(run) {111    if ('seats' in run && run.seats.length) {112      // eslint-disable-next-line consistent-return113      const upgradeableSeats = run.seats.filter((seat) => {114        const upgradeableSeatTypes = ['verified', 'professional', 'no-id-professional', 'credit'];115        return upgradeableSeatTypes.indexOf(seat.type) >= 0;116      });117      if (upgradeableSeats.length > 0) {118        const upgradeableSeat = upgradeableSeats[0];119        if (upgradeableSeat) {120          const currency = upgradeableSeat.currency;121          if (currency === 'USD') {122            return `$${upgradeableSeat.price}`;123          }124          return `${upgradeableSeat.price} ${currency}`;125        }126      }127    }128    return null;129  }130  formatDateString(run) {131    const pacingType = run.pacing_type;132    let dateString;133    const start = CourseCardModel.valueIsDefined(run.start_date) ?134      run.advertised_start || run.start_date :135      this.get('start_date');136    const end = CourseCardModel.valueIsDefined(run.end_date) ? run.end_date : this.get('end_date');137    const now = new Date();138    const startDate = new Date(start);139    const endDate = new Date(end);140    if (pacingType === 'self_paced') {141      if (start) {142        dateString = startDate > now ?143          StringUtils.interpolate(gettext('(Self-paced) Starts {start}'), { start }) :144          StringUtils.interpolate(gettext('(Self-paced) Started {start}'), { start });145      } else if (end && endDate > now) {146        dateString = StringUtils.interpolate(gettext('(Self-paced) Ends {end}'), { end });147      } else if (end && endDate < now) {148        dateString = StringUtils.interpolate(gettext('(Self-paced) Ended {end}'), { end });149      }150    } else if (start && end) {151      dateString = `${start} - ${end}`;152    } else if (start) {153      dateString = startDate > now ?154                                StringUtils.interpolate(gettext('Starts {start}'), { start }) :155                                StringUtils.interpolate(gettext('Started {start}'), { start });156    } else if (end) {157      dateString = StringUtils.interpolate(gettext('Ends {end}'), { end });158    }159    return dateString;160  }161  static valueIsDefined(val) {162    return !([undefined, 'None', null].indexOf(val) >= 0);163  }164  setActiveCourseRun(courseRun, userPreferences) {165    let startDateString;166    let courseTitleLink = '';167    const isEnrolled = this.isEnrolledInSession() && courseRun.key;168    if (courseRun) {169      if (CourseCardModel.valueIsDefined(courseRun.advertised_start)) {170        startDateString = courseRun.advertised_start;171      } else {172        startDateString = CourseCardModel.formatDate(courseRun.start, userPreferences);173      }174      if (isEnrolled && courseRun.course_url) {175        courseTitleLink = courseRun.course_url;176      } else if (!isEnrolled && courseRun.marketing_url) {177        courseTitleLink = CourseCardModel.updateMarketingUrl(courseRun);178      }179      this.set({180        certificate_url: courseRun.certificate_url,181        course_run_key: courseRun.key || '',182        course_url: courseRun.course_url || '',183        title: this.context.title,184        end_date: CourseCardModel.formatDate(courseRun.end, userPreferences),185        enrollable_course_runs: this.getEnrollableCourseRuns(),186        is_course_ended: courseRun.is_course_ended,187        is_enrolled: isEnrolled,188        is_enrollment_open: courseRun.is_enrollment_open,189        course_key: this.context.key,190        user_entitlement: this.context.user_entitlement,191        is_unfulfilled_entitlement: this.context.user_entitlement && !isEnrolled,192        marketing_url: courseRun.marketing_url,193        mode_slug: courseRun.type,194        start_date: startDateString,195        upcoming_course_runs: this.getUpcomingCourseRuns(),196        upgrade_url: courseRun.upgrade_url,197        price: CourseCardModel.getCertificatePriceString(courseRun),198        course_title_link: courseTitleLink,199        is_mobile_only: courseRun.is_mobile_only || false,200      });201      // This is used to render the date for completed and in progress courses202      this.set({ dateString: this.formatDateString(courseRun) });203    }204  }205  setUnselected() {206    // Called to reset the model back to the unselected state.207    const unselectedCourseRun = CourseCardModel.getUnselectedCourseRun(this.get('enrollable_course_runs'));208    this.setActiveCourseRun(unselectedCourseRun);209  }210  updateCourseRun(courseRunKey) {211    const selectedCourseRun = this.get('course_runs').find(run => run.key === courseRunKey);212    if (selectedCourseRun) {213      // Update the current context to set the course run to the enrolled state214      this.context.course_runs.forEach((run) => {215        Object.assign(run, {216          is_enrolled: run.is_enrolled || run.key === selectedCourseRun.key,217        });218      });219      this.setActiveCourseRun(selectedCourseRun);220    }221  }222  // update marketing url for deep linking if is_mobile_only true223  static updateMarketingUrl(courseRun) {224    if (courseRun.is_mobile_only === true) {225      const marketingUrl = courseRun.marketing_url;226      let href = marketingUrl;227      if (marketingUrl.indexOf('course_info?path_id') < 0) {228        const start = marketingUrl.indexOf('course/');229        let path;230        if (start > -1) {231          path = marketingUrl.substr(start);232        }233        href = `edxapp://course_info?path_id=${path}`;234      }235      return href;236    }237    return courseRun.marketing_url;238  }239}...test-test.js
Source:test-test.js  
...35});36test(function runEmptyTest() {37  testInstance.testFn = sinon.spy();38  var runCb = sinon.spy();39  testInstance.run(runCb);40  assert.ok(testInstance.testFn.called);41  var doneErr = runCb.args[0][0];42  assert.ok(!doneErr);43  assert.ok(testInstance._ended);44});45test(function runSyncException() {46  var err = new Error('something went wrong');47  testInstance.testFn = function() {48    sandboxProcess.emit('uncaughtException', err);49  };50  var runCb = sinon.spy();51  testInstance.run(runCb);52  assert.strictEqual(testInstance.error, err);53  assert.strictEqual(runCb.args[0][0], err);54});55test(function runSyncExceptionInAsyncTest() {56  var err = new Error('something went wrong');57  testInstance.testFn = function(done) {58    sandboxProcess.emit('uncaughtException', err);59  };60  var runCb = sinon.spy();61  testInstance.run(runCb);62  assert.strictEqual(testInstance.error, err);63  assert.strictEqual(runCb.args[0][0], err);64});65test(function runAsyncTest() {66  var clock = sinon.useFakeTimers();;67  testInstance.testFn = function(done) {68    setTimeout(function() {69      done();70    }, 100);71  };72  var runCb = sinon.spy();73  testInstance.run(runCb);74  clock.tick(99);75  assert.ok(!runCb.called);76  clock.tick(1);77  assert.ok(runCb.called);78  assert.ok(testInstance._ended);79  clock.restore();80});81test(function runAsyncTestDoneTwice() {82  testInstance.testFn = function(done) {83    done();84    done();85  };86  var runCb = sinon.spy();87  testInstance.run(runCb);88  assert.strictEqual(runCb.callCount, 1);89});90test(function runAsyncTestError() {91  var clock = sinon.useFakeTimers();;92  var err = new Error('ouch');93  testInstance.testFn = function(done) {94    setTimeout(function() {95      done(err);96    }, 100);97  };98  var runCb = sinon.spy();99  testInstance.run(runCb);100  clock.tick(100);101  assert.strictEqual(runCb.args[0][0], err);102  clock.restore();103});104test(function runAsyncTestException() {105  testInstance.testFn = function(done) {106  };107  var runCb = sinon.spy();108  testInstance.run(runCb);109  var err = new Error('oh no');110  sandboxProcess.emit('uncaughtException', err);111  assert.strictEqual(runCb.args[0][0], err);112  var listeners = [].concat(sandboxProcess.listeners('uncaughtException'));113  sandboxProcess.removeAllListeners('uncaughtException');114  assert.strictEqual(listeners.length, 0);115});116test(function runBeforeAndAfterSync() {117  sinon.spy(testInstance, 'beforeFn');118  sinon.spy(testInstance, 'afterFn');119  testInstance.testFn = function() {120    assert.ok(testInstance.beforeFn.called);121  };122  var runCb = sinon.spy();123  testInstance.run(runCb);124  assert.equal(runCb.args[0][0], null);125  assert.ok(runCb.called);126  assert.ok(testInstance.afterFn.called);127});128test(function afterExecutesEvenOnTestError() {129  sinon.spy(testInstance, 'afterFn');130  var err = new Error('oh noes');131  testInstance.testFn = function() {132    sandboxProcess.emit('uncaughtException', err);133  };134  var runCb = sinon.spy();135  testInstance.run(runCb);136  assert.strictEqual(runCb.args[0][0], err);137  assert.ok(testInstance.afterFn.called);138});139test(function asyncTimeout() {140  var clock = sinon.useFakeTimers();;141  Sandbox.globals.setTimeout = setTimeout;142  Sandbox.globals.Date = Date;143  testInstance.testFn = function(done) {};144  var timeout = testInstance.timeout = 100;145  var runCb = sinon.spy();146  testInstance.run(runCb);147  clock.tick(99);148  assert.strictEqual(runCb.called, false);149  clock.tick(1);150  var doneErr = runCb.args[0][0];151  assert.ok(doneErr.timeout);152  assert.ok(doneErr.message.match(/timeout/i));153  assert.ok(doneErr.message.indexOf('exceeded ' + timeout + 'ms') > -1);154  assert.ok(doneErr.message.indexOf('took 100ms') > -1);155  clock.restore()156  Sandbox.globals.setTimeout = setTimeout;157  Sandbox.globals.Date = Date;158});159test(function syncTimeout() {160  testInstance.testFn = function() {161  };162  var timeout = testInstance.timeout = -1;163  var runCb = sinon.spy();164  testInstance.run(runCb);165  assert.strictEqual(runCb.called, true);166  var doneErr = runCb.args[0][0];167  assert.ok(doneErr.message.match(/timeout/i));168  assert.ok(doneErr.message.indexOf('exceeded ' + timeout + 'ms') > -1);169});170test(function alterTimeout() {171  var clock = sinon.useFakeTimers();;172  Sandbox.globals.setTimeout = setTimeout;173  Sandbox.globals.clearTimeout = clearTimeout;174  Sandbox.globals.Date = Date;175  testInstance.testFn = function(done) {};176  testInstance.timeout = 100;177  var runCb = sinon.spy();178  testInstance.run(runCb);179  clock.tick(99);180  assert.strictEqual(runCb.called, false);181  testInstance.setTimeout(101);182  clock.tick(100);183  assert.strictEqual(runCb.called, false);184  clock.tick(1);185  assert.strictEqual(runCb.called, true);186  clock.restore()187  Sandbox.globals.setTimeout = setTimeout;188  Sandbox.globals.clearTimeout = clearTimeout;189  Sandbox.globals.Date = Date;190});191test(function clearsAysyncTimeoutOnSuccess() {192  var realClearTimeout = clearTimeout;193  var timeoutId = 23;194  Sandbox.globals.setTimeout = sinon.stub().returns(timeoutId);195  Sandbox.globals.clearTimeout = sinon.stub();196  testInstance.testFn = function(done) {197    done();198  };199  testInstance.timeout = 100;200  var runCb = sinon.spy();201  testInstance.run(runCb);202  assert.ok(runCb.called);203  assert.ok(Sandbox.globals.clearTimeout.calledWith(timeoutId));204  Sandbox.globals.clearTimeout = realClearTimeout;205});206test(function cancelTimeout() {207  var clock = sinon.useFakeTimers();;208  Sandbox.globals.setTimeout = setTimeout;209  Sandbox.globals.clearTimeout = clearTimeout;210  Sandbox.globals.Date = Date;211  testInstance.testFn = function(done) {};212  testInstance.timeout = 100;213  var runCb = sinon.spy();214  testInstance.run(runCb);215  testInstance.setTimeout(0);216  clock.tick(100);217  assert.ok(!testInstance._ended);218  testInstance.end();219  assert.ok(testInstance._ended);220  var doneErr = runCb.args[0][0];221  assert.ok(!doneErr);222  clock.restore()223  Sandbox.globals.setTimeout = setTimeout;224  Sandbox.globals.clearTimeout = clearTimeout;225  Sandbox.globals.Date = Date;226});227test(function addTraceInfoForTimeout() {228  var file = __dirname + '/imaginary.js';...Run.js
Source:Run.js  
1/*2 * This file is part of the Reproducible Open Benchmarks for Data Analysis3 * Platform (ROB).4 *5 * Copyright (C) [2019-2020] NYU.6 *7 * ROB is free software; you can redistribute it and/or modify it under the8 * terms of the MIT License; see LICENSE file for more details.9 */10import { selectDialog } from './Benchmark';11import { fetchApiResource, postRequest } from './Requests';12import { SHOW_RUNS } from '../resources/Dialog';13/*14 * Action types15 */16// Run handle17export const FETCH_RUN_ERROR = 'FETCH_RUN_ERROR';18export const FETCH_RUN_START = 'FETCH_RUN_START';19export const FETCH_RUN_SUCCESS = 'FETCH_RUN_SUCCESS';20// Run listing21export const FETCH_RUNS_ERROR = 'FETCH_RUNS_ERROR';22export const FETCH_RUNS_SUCCESS = 'FETCH_RUNS_SUCCESS';23// Run submission24export const SUBMIT_RUN_ERROR = 'SUBMIT_RUN_ERROR';25export const SUBMIT_RUN_START = 'SUBMIT_RUN_START';26export const SUBMIT_RUN_SUCCESS = 'SUBMIT_RUN_SUCCESS';27/*28 * Actions29 */30// -- Errors ------------------------------------------------------------------31export const dismissFetchRunError = () => (fetchRunError());32export const dismissFetchRunsError = () => (fetchRunsError());33export const dismissSubmitRunError = () => (submitRunError());34const fetchRunError = (msg) => ({type: FETCH_RUN_ERROR, payload: msg});35const fetchRunsError = (msg) => ({type: FETCH_RUNS_ERROR, payload: msg});36const submitRunError = (msg) => ({type: SUBMIT_RUN_ERROR, payload: msg});37// -- Run handle --------------------------------------------------------------38export function fetchRun(api, run) {39    return fetchApiResource(40        api.urls.getRun(run.id),41        fetchRunSuccess,42        fetchRunError,43        fetchRunStart,44    );45}46const fetchRunStart = () => ({type: FETCH_RUN_START});47const fetchRunSuccess = (run) => ({type: FETCH_RUN_SUCCESS, payload: run})48export function cancelRun(api, submission, run) {49    return postRequest(50        api.urls.cancelRun(run.id),51        {reason: 'Canceled at user request'},52        (json) => (cancelRunSuccess(api, submission, json)),53        fetchRunError,54        fetchRunStart,55        'PUT'56    );57}58function cancelRunSuccess(api, submission, run) {59    return dispatch => {60        dispatch(fetchRuns(api, submission))61        return dispatch(fetchRunSuccess(run))62    }63}64// -- Run listing -------------------------------------------------------------65export function fetchRuns(api, submission, selectedRun) {66    return fetchApiResource(67        api.urls.listRuns(submission.id),68        (json) => {return dispatch => {69            // If the selected run is given, check whether the run state has70            // changed. If there is a change in state, fetch the run handle.71            if (selectedRun != null) {72                const run = json.runs.find((r) => (r.id === selectedRun.id));73                if (run != null) {74                    if (run.state !== selectedRun.state) {75                        dispatch(fetchRun(api, selectedRun));76                    }77                }78            }79            return dispatch({type: FETCH_RUNS_SUCCESS, payload: json})80        }},81        fetchRunsError82    );83}84// -- Submit run --------------------------------------------------------------85export function submitRun(api, submission, data) {86    return postRequest(87        api.urls.submitRun(submission.id),88        data,89        (json) => (submitRunSuccess(api, submission)),90        submitRunError,91        () => ({type: SUBMIT_RUN_START})92    );93}94function submitRunSuccess(api, submission) {95    return dispatch => {96        dispatch({type: SUBMIT_RUN_SUCCESS});97        dispatch(selectDialog(api, SHOW_RUNS));98        return dispatch(fetchRuns(api, submission))99    }...test.js
Source:test.js  
...6  var run = thunky(function (cb) {7    ran++8    cb()9  })10  run(function () {11    t.same(ran, 1, 'ran once')12  })13  run(function () {14    t.same(ran, 1, 'ran once')15  })16  run(function () {17    t.same(ran, 1, 'ran once')18  })19})20tape('run only once async', function (t) {21  t.plan(3)22  var ran = 023  var run = thunky(function (cb) {24    process.nextTick(function () {25      ran++26      cb()27    })28  })29  run(function () {30    t.same(ran, 1, 'ran once')31  })32  run(function () {33    t.same(ran, 1, 'ran once')34  })35  run(function () {36    t.same(ran, 1, 'ran once')37  })38})39tape('re-run on error', function (t) {40  t.plan(3)41  var ran = 042  var run = thunky(function (cb) {43    ran++44    cb(new Error('stop'))45  })46  run(function () {47    t.same(ran, 1, 'ran once')48    run(function () {49      t.same(ran, 2, 'ran once')50      run(function () {51        t.same(ran, 3, 'ran once')52      })53    })54  })55})56tape('pass arguments', function (t) {57  t.plan(6)58  var ran = 059  var run = thunky(function (fn) {60    ran++61    fn({ hello: 'world' })62  })63  run(function (val) {64    t.same(ran, 1, 'ran once')65    t.same(val, { hello: 'world' })66    run(function (val) {67      t.same(ran, 1, 'ran once')68      t.same(val, { hello: 'world' })69      run(function (val) {70        t.same(ran, 1, 'ran once')71        t.same(val, { hello: 'world' })72      })73    })74  })75})76tape('callback is optional', function (t) {77  t.plan(2)78  var ran = 079  var run = thunky(function (fn) {80    ran++81    fn({ hello: 'world' })82  })83  run()84  run(function (val) {85    t.same(ran, 1, 'ran once')86    t.same(val, { hello: 'world' })87  })88})89tape('always async', function (t) {90  t.plan(2)91  var run = thunky(function (cb) {92    process.nextTick(cb)93  })94  var sync = true95  run(function () {96    t.ok(!sync, 'not sync')97    var innerSync = true98    run(function () {99      t.ok(!innerSync, 'not sync')100    })101    innerSync = false102  })103  sync = false...repl.js
Source:repl.js  
1import runCLI from "../../__test_helpers__/runCLI";2import stripAnsi from "strip-ansi";3describe("repl", () => {4  let pty;5  const runRepl = () => runCLI(["-i"], { pty });6  beforeEach(() => {7    pty = true;8  });9  it("starts a repl", async () => {10    const run = runRepl();11    await run.outputContains("> ");12    run.kill();13  });14  it("evaluates each written line and prints back `util.inspect`ed values", async () => {15    const run = runRepl();16    await run.outputContains("> ");17    run.write("document\n");18    await run.outputContains("HTMLDocument { location: [Getter/Setter] }");19    run.write("2 + 2\n");20    await run.outputContains("4");21    run.kill();22  });23  describe("with a TTY", () => {24    it("uses colors", async () => {25      const run = runRepl();26      await run.outputContains("> ");27      run.kill();28      expect(stripAnsi(run.result.stdout)).not.toEqual(run.result.stdout);29    });30  });31  describe("without a TTY", () => {32    beforeEach(() => {33      pty = false;34    });35    it("does not use colors", async () => {36      const run = runRepl();37      await run.outputContains("> ");38      run.kill();39      expect(stripAnsi(run.result.stdout)).toEqual(run.result.stdout);40    });41  });...Using AI Code Generation
1const Chromeless = require('chromeless').Chromeless2async function run() {3  const chromeless = new Chromeless()4    .type('chromeless', 'input[name="q"]')5    .press(13)6    .wait('#resultStats')7    .screenshot()8  await chromeless.end()9}10run().catch(console.error.bind(console))11### `new Chromeless(options)`Using AI Code Generation
1const chromeless = new Chromeless()2  .type('chromeless', 'input[name="q"]')3  .press(13)4  .wait('#resultStats')5  .screenshot()6await chromeless.end()7{8  "scripts": {9  },10  "dependencies": {11  }12}13const Chromeless = require('chromeless')()14const chromeless = new Chromeless()15  .screenshot()16await chromeless.end()17Chromeless(options)Using AI Code Generation
1const chromeless = new Chromeless();2  .type('chromeless', 'input[name="q"]')3  .press(13)4  .wait('#resultStats')5  .screenshot();6await chromeless.end();Using AI Code Generation
1const Chromeless = require('chromeless').Chromeless;2const chromeless = new Chromeless();3  .type('chromeless', 'input[name="q"]')4  .press(13)5  .wait('#resultStats')6  .evaluate(() => {7  })8  .then(title => console.log('Title is: ' + title))9  .catch(console.error.bind(console))10  .then(() => chromeless.end());11const chromeless = new Chromeless()12  .type('chromeless', 'input[name="q"]')13  .press(13)14  .wait('#resultStats')15  .screenshot()16  .then(screenshot => console.log(screenshot))17  .catch(console.error.bind(console))18  .then(() => chromeless.end())Using AI Code Generation
1const Chromeless = require('chromeless').Chromeless2const chromeless = new Chromeless()3    .type('chromeless', 'input[name="q"]')4    .press(13)5    .wait('#resultStats')6    .evaluate(() => {7    })8    .end()9    .then(console.log)10    .catch(console.error)11const Chromeless = require('chromeless').Chromeless12const chromeless = new Chromeless()13    .type('chromeless', 'input[name="q"]')14    .press(13)15    .wait('#resultStats')16    .evaluate(() => {17    })18    .end()19    .then(console.log)20    .catch(console.error)21### `new Chromeless(options)`22- `options` (optional) - Object with the following properties:23  - `cdp` - Object. Additional chrome debug protocol options. See [chrome-remote-interface](Using AI Code Generation
1const Chromeless = require('chromeless').Chromeless2const chromeless = new Chromeless()3  .type('chromeless', 'input[name="q"]')4  .press(13)5  .wait('#resultStats')6  .evaluate(() => {7  })8  .then((title) => {9  })10  .catch((err) => {11    console.error(err)12  })13  .then(() => {14    chromeless.end()15  })Using AI Code Generation
1const Chromeless = require('chromeless').Chromeless2async function run() {3  const chromeless = new Chromeless()4    .type('chromeless', 'input[name="q"]')5    .press(13)6    .wait('#resultStats')7    .screenshot()8  await chromeless.end()9}10run().catch(console.error.bind(console))11{12  "scripts": {13  },14  "dependencies": {15  }16}17{18  "scripts": {19  },20  "dependencies": {21  }22}23{24  "scripts": {25  },26  "dependencies": {27  }28}29{30  "scripts": {31  },32  "dependencies": {33  }34}35{36  "scripts": {37  },38  "dependencies": {39  }40}Using AI Code Generation
1const chromeless = require('chromeless')()2async function run() {3    .goto(url)4    .type('chromeless', 'input[name="q"]')5    .press(13)6    .wait('#resultStats')7    .screenshot()8  await chromeless.end()9}10run().catch(console.error.bind(console))11Chromeless can be used with AWS Lambda. This is useful if you want to run Chromeless on a schedule or as a webhook. Checkout [chromeless-aws-lambda](Using AI Code Generation
1const chromeless = require('chromeless')()2const fs = require('fs');3const path = require('path');4const util = require('util');5const writeFile = util.promisify(fs.writeFile);6const readFile = util.promisify(fs.readFile);7async function run() {8    .goto(url)9    .wait('body')10    .html()11  await writeFile(path.join(__dirname, 'test.html'), html);12  await chromeless.end()13}14run().catch(console.error.bind(console))Using AI Code Generation
1const Chromeless = require('chromeless').Chromeless2async function run() {3  const chromeless = new Chromeless()4    .type('chromeless', 'input[name="q"]')5    .press(13)6    .wait('#resultStats')7    .screenshot()8  await chromeless.end()9}10run().catch(console.error.bind(console))11{12  "scripts": {13  },14  "devDependencies": {15  }16}17{18  "dependencies": {19    "chromeless": {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!!
