How to use user.ensureAuthToken method in Cypress

Best JavaScript code snippet using cypress

project_spec.js

Source:project_spec.js Github

copy

Full Screen

1require('../spec_helper')2const mockedEnv = require('mocked-env')3const path = require('path')4const commitInfo = require('@cypress/commit-info')5const Fixtures = require('../support/helpers/fixtures')6const api = require(`${root}lib/api`)7const user = require(`${root}lib/user`)8const cache = require(`${root}lib/cache`)9const config = require(`${root}lib/config`)10const scaffold = require(`${root}lib/scaffold`)11const { ServerE2E } = require(`${root}lib/server-e2e`)12const { ProjectE2E } = require(`${root}lib/project-e2e`)13const Automation = require(`${root}lib/automation`)14const savedState = require(`${root}lib/saved_state`)15const preprocessor = require(`${root}lib/plugins/preprocessor`)16const plugins = require(`${root}lib/plugins`)17const { fs } = require(`${root}lib/util/fs`)18const settings = require(`${root}lib/util/settings`)19const Watchers = require(`${root}lib/watchers`)20const { SocketE2E } = require(`${root}lib/socket-e2e`)21xdescribe('lib/project-e2e', () => {22  beforeEach(function () {23    Fixtures.scaffold()24    this.todosPath = Fixtures.projectPath('todos')25    this.idsPath = Fixtures.projectPath('ids')26    this.pristinePath = Fixtures.projectPath('pristine')27    return settings.read(this.todosPath).then((obj = {}) => {28      ({ projectId: this.projectId } = obj)29      return config.set({ projectName: 'project', projectRoot: '/foo/bar' })30      .then((config1) => {31        this.config = config132        this.project = new ProjectE2E(this.todosPath)33      })34    })35  })36  afterEach(function () {37    Fixtures.remove()38    if (this.project) {39      this.project.close()40    }41  })42  it('requires a projectRoot', () => {43    const fn = () => new ProjectE2E()44    expect(fn).to.throw('Instantiating lib/project requires a projectRoot!')45  })46  it('always resolves the projectRoot to be absolute', () => {47    const p = new ProjectE2E('../foo/bar')48    expect(p.projectRoot).not.to.eq('../foo/bar')49    expect(p.projectRoot).to.eq(path.resolve('../foo/bar'))50  })51  context('#saveState', () => {52    beforeEach(function () {53      const integrationFolder = 'the/save/state/test'54      sinon.stub(config, 'get').withArgs(this.todosPath).resolves({ integrationFolder })55      sinon.stub(this.project, 'determineIsNewProject').withArgs(integrationFolder).resolves(false)56      this.project.cfg = { integrationFolder }57      return savedState.create(this.project.projectRoot)58      .then((state) => state.remove())59    })60    afterEach(function () {61      return savedState.create(this.project.projectRoot)62      .then((state) => state.remove())63    })64    it('saves state without modification', function () {65      return this.project.saveState()66      .then((state) => expect(state).to.deep.eq({}))67    })68    it('adds property', function () {69      return this.project.saveState()70      .then(() => this.project.saveState({ foo: 42 }))71      .then((state) => expect(state).to.deep.eq({ foo: 42 }))72    })73    it('adds second property', function () {74      return this.project.saveState()75      .then(() => this.project.saveState({ foo: 42 }))76      .then(() => this.project.saveState({ bar: true }))77      .then((state) => expect(state).to.deep.eq({ foo: 42, bar: true }))78    })79    it('modifes property', function () {80      return this.project.saveState()81      .then(() => this.project.saveState({ foo: 42 }))82      .then(() => this.project.saveState({ foo: 'modified' }))83      .then((state) => expect(state).to.deep.eq({ foo: 'modified' }))84    })85  })86  context('#getConfig', () => {87    const integrationFolder = 'foo/bar/baz'88    beforeEach(function () {89      sinon.stub(config, 'get').withArgs(this.todosPath, { foo: 'bar' }).resolves({ baz: 'quux', integrationFolder })90      sinon.stub(this.project, 'determineIsNewProject').withArgs(integrationFolder).resolves(false)91    })92    it('calls config.get with projectRoot + options + saved state', function () {93      return savedState.create(this.todosPath)94      .then((state) => {95        sinon.stub(state, 'get').resolves({ reporterWidth: 225 })96        this.project.getConfig({ foo: 'bar' })97        .then((cfg) => {98          expect(cfg).to.deep.eq({99            integrationFolder,100            isNewProject: false,101            baz: 'quux',102            state: {103              reporterWidth: 225,104            },105          })106        })107      })108    })109    it('resolves if cfg is already set', function () {110      this.project.cfg = {111        integrationFolder,112        foo: 'bar',113      }114      return this.project.getConfig()115      .then((cfg) => {116        expect(cfg).to.deep.eq({117          integrationFolder,118          foo: 'bar',119        })120      })121    })122    it('sets cfg.isNewProject to false when state.showedOnBoardingModal is true', function () {123      return savedState.create(this.todosPath)124      .then((state) => {125        sinon.stub(state, 'get').resolves({ showedOnBoardingModal: true })126        this.project.getConfig({ foo: 'bar' })127        .then((cfg) => {128          expect(cfg).to.deep.eq({129            integrationFolder,130            isNewProject: false,131            baz: 'quux',132            state: {133              showedOnBoardingModal: true,134            },135          })136        })137      })138    })139    it('does not set cfg.isNewProject when cfg.isTextTerminal', function () {140      const cfg = { isTextTerminal: true }141      config.get.resolves(cfg)142      sinon.stub(this.project, '_setSavedState').resolves(cfg)143      return this.project.getConfig({ foo: 'bar' })144      .then((cfg) => {145        expect(cfg).not.to.have.property('isNewProject')146      })147    })148  })149  context('#open', () => {150    beforeEach(function () {151      sinon.stub(this.project, 'watchSettingsAndStartWebsockets').resolves()152      sinon.stub(this.project, 'checkSupportFile').resolves()153      sinon.stub(this.project, 'scaffold').resolves()154      sinon.stub(this.project, 'getConfig').resolves(this.config)155      sinon.stub(ServerE2E.prototype, 'open').resolves([])156      sinon.stub(ServerE2E.prototype, 'reset')157      sinon.stub(config, 'updateWithPluginValues').returns(this.config)158      sinon.stub(scaffold, 'plugins').resolves()159      sinon.stub(plugins, 'init').resolves()160    })161    it('calls #watchSettingsAndStartWebsockets with options + config', function () {162      const opts = { changeEvents: false, onAutomationRequest () {} }163      this.project.cfg = {}164      return this.project.open(opts).then(() => {165        expect(this.project.watchSettingsAndStartWebsockets).to.be.calledWith(opts, this.project.cfg)166      })167    })168    it('calls #scaffold with server config promise', function () {169      return this.project.open().then(() => {170        expect(this.project.scaffold).to.be.calledWith(this.config)171      })172    })173    it('calls #checkSupportFile with server config when scaffolding is finished', function () {174      return this.project.open().then(() => {175        expect(this.project.checkSupportFile).to.be.calledWith(this.config)176      })177    })178    it('calls #getConfig options', function () {179      const opts = {}180      return this.project.open(opts).then(() => {181        expect(this.project.getConfig).to.be.calledWith(opts)182      })183    })184    it('initializes the plugins', function () {185      return this.project.open({}).then(() => {186        expect(plugins.init).to.be.called187      })188    })189    it('calls support.plugins with pluginsFile directory', function () {190      return this.project.open({}).then(() => {191        expect(scaffold.plugins).to.be.calledWith(path.dirname(this.config.pluginsFile))192      })193    })194    it('calls options.onError with plugins error when there is a plugins error', function () {195      const onError = sinon.spy()196      const err = {197        name: 'plugin error name',198        message: 'plugin error message',199      }200      return this.project.open({ onError }).then(() => {201        const pluginsOnError = plugins.init.lastCall.args[1].onError202        expect(pluginsOnError).to.be.a('function')203        pluginsOnError(err)204        expect(onError).to.be.calledWith(err)205      })206    })207    it('updates config.state when saved state changes', function () {208      sinon.spy(this.project, 'saveState')209      const options = {}210      return this.project.open(options)211      .then(() => options.onSavedStateChanged({ autoScrollingEnabled: false }))212      .then(() => this.project.getConfig())213      .then((config) => {214        expect(this.project.saveState).to.be.calledWith({ autoScrollingEnabled: false })215        expect(config.state).to.eql({ autoScrollingEnabled: false })216      })217    })218    // TODO: skip this for now219    it.skip('watches cypress.json', function () {220      return this.server.open().bind(this).then(() => {221        expect(Watchers.prototype.watch).to.be.calledWith('/Users/brian/app/cypress.json')222      })223    })224    // TODO: skip this for now225    it.skip('passes watchers to Socket.startListening', function () {226      const options = {}227      return this.server.open(options).then(() => {228        const { startListening } = SocketE2E.prototype229        expect(startListening.getCall(0).args[0]).to.be.instanceof(Watchers)230        expect(startListening.getCall(0).args[1]).to.eq(options)231      })232    })233    it('attaches warning to non-chrome browsers when chromeWebSecurity:false', function () {234      Object.assign(this.config, {235        browsers: [{ family: 'chromium', name: 'Canary' }, { family: 'some-other-family', name: 'some-other-name' }],236        chromeWebSecurity: false,237      })238      return this.project.open()239      .then(() => this.project.getConfig())240      .then((config) => {241        expect(config.chromeWebSecurity).eq(false)242        expect(config.browsers).deep.eq([243          {244            family: 'chromium',245            name: 'Canary',246          },247          {248            family: 'some-other-family',249            name: 'some-other-name',250            warning: `\251Your project has set the configuration option: \`chromeWebSecurity: false\`252This option will not have an effect in Some-other-name. Tests that rely on web security being disabled will not run as expected.\253`,254          },255        ])256        expect(config).ok257      })258    })259  })260  context('#close', () => {261    beforeEach(function () {262      this.project = new ProjectE2E('/_test-output/path/to/project-e2e')263      sinon.stub(this.project, 'getConfig').resolves(this.config)264      sinon.stub(user, 'ensureAuthToken').resolves('auth-token-123')265    })266    it('closes server', function () {267      this.project.server = sinon.stub({ close () {} })268      return this.project.close().then(() => {269        expect(this.project.server.close).to.be.calledOnce270      })271    })272    it('closes watchers', function () {273      this.project.watchers = sinon.stub({ close () {} })274      return this.project.close().then(() => {275        expect(this.project.watchers.close).to.be.calledOnce276      })277    })278    it('can close when server + watchers arent open', function () {279      return this.project.close()280    })281  })282  context('#reset', () => {283    beforeEach(function () {284      this.project = new ProjectE2E(this.pristinePath)285      this.project.automation = { reset: sinon.stub() }286      this.project.server = { reset: sinon.stub() }287    })288    it('resets server + automation', function () {289      return this.project.reset()290      .then(() => {291        expect(this.project.automation.reset).to.be.calledOnce292        expect(this.project.server.reset).to.be.calledOnce293      })294    })295  })296  context('#getRuns', () => {297    beforeEach(function () {298      this.project = new ProjectE2E(this.todosPath)299      sinon.stub(settings, 'read').resolves({ projectId: 'id-123' })300      sinon.stub(api, 'getProjectRuns').resolves('runs')301      sinon.stub(user, 'ensureAuthToken').resolves('auth-token-123')302    })303    it('calls api.getProjectRuns with project id + session', function () {304      return this.project.getRuns().then((runs) => {305        expect(api.getProjectRuns).to.be.calledWith('id-123', 'auth-token-123')306        expect(runs).to.equal('runs')307      })308    })309  })310  context('#scaffold', () => {311    beforeEach(function () {312      this.project = new ProjectE2E('/_test-output/path/to/project-e2e')313      sinon.stub(scaffold, 'integration').resolves()314      sinon.stub(scaffold, 'fixture').resolves()315      sinon.stub(scaffold, 'support').resolves()316      sinon.stub(scaffold, 'plugins').resolves()317      this.obj = { projectRoot: 'pr', fixturesFolder: 'ff', integrationFolder: 'if', supportFolder: 'sf', pluginsFile: 'pf/index.js' }318    })319    it('calls scaffold.integration with integrationFolder', function () {320      return this.project.scaffold(this.obj).then(() => {321        expect(scaffold.integration).to.be.calledWith(this.obj.integrationFolder)322      })323    })324    it('calls fixture.scaffold with fixturesFolder', function () {325      return this.project.scaffold(this.obj).then(() => {326        expect(scaffold.fixture).to.be.calledWith(this.obj.fixturesFolder)327      })328    })329    it('calls support.scaffold with supportFolder', function () {330      return this.project.scaffold(this.obj).then(() => {331        expect(scaffold.support).to.be.calledWith(this.obj.supportFolder)332      })333    })334    it('does not call support.plugins if config.pluginsFile is falsey', function () {335      this.obj.pluginsFile = false336      return this.project.scaffold(this.obj).then(() => {337        expect(scaffold.plugins).not.to.be.called338      })339    })340    describe('forced', () => {341      let resetEnv342      beforeEach(function () {343        this.obj.isTextTerminal = true344        resetEnv = mockedEnv({345          CYPRESS_INTERNAL_FORCE_SCAFFOLD: '1',346        })347      })348      afterEach(() => {349        resetEnv()350      })351      it('calls scaffold when forced by environment variable', function () {352        return this.project.scaffold(this.obj).then(() => {353          expect(scaffold.integration).to.be.calledWith(this.obj.integrationFolder)354          expect(scaffold.fixture).to.be.calledWith(this.obj.fixturesFolder)355          expect(scaffold.support).to.be.calledWith(this.obj.supportFolder)356        })357      })358    })359    describe('not forced', () => {360      let resetEnv361      beforeEach(function () {362        this.obj.isTextTerminal = true363        resetEnv = mockedEnv({364          CYPRESS_INTERNAL_FORCE_SCAFFOLD: undefined,365        })366      })367      afterEach(() => {368        resetEnv()369      })370      it('does not scaffold integration folder', function () {371        return this.project.scaffold(this.obj).then(() => {372          expect(scaffold.integration).to.not.be.calledWith(this.obj.integrationFolder)373          expect(scaffold.fixture).to.not.be.calledWith(this.obj.fixturesFolder)374          // still scaffolds support folder due to old logic375          expect(scaffold.support).to.be.calledWith(this.obj.supportFolder)376        })377      })378    })379  })380  context('#watchSettings', () => {381    beforeEach(function () {382      this.project = new ProjectE2E('/_test-output/path/to/project-e2e')383      this.project.server = { startWebsockets () {} }384      sinon.stub(settings, 'pathToConfigFile').returns('/path/to/cypress.json')385      sinon.stub(settings, 'pathToCypressEnvJson').returns('/path/to/cypress.env.json')386      this.watch = sinon.stub(this.project.watchers, 'watch')387    })388    it('watches cypress.json and cypress.env.json', function () {389      this.project.watchSettingsAndStartWebsockets({ onSettingsChanged () {} })390      expect(this.watch).to.be.calledTwice391      expect(this.watch).to.be.calledWith('/path/to/cypress.json')392      expect(this.watch).to.be.calledWith('/path/to/cypress.env.json')393    })394    it('sets onChange event when {changeEvents: true}', function (done) {395      this.project.watchSettingsAndStartWebsockets({ onSettingsChanged: () => done() })396      // get the object passed to watchers.watch397      const obj = this.watch.getCall(0).args[1]398      expect(obj.onChange).to.be.a('function')399      obj.onChange()400    })401    it('does not call watch when {changeEvents: false}', function () {402      this.project.watchSettingsAndStartWebsockets({ onSettingsChanged: undefined })403      expect(this.watch).not.to.be.called404    })405    it('does not call onSettingsChanged when generatedProjectIdTimestamp is less than 1 second', function () {406      let timestamp = new Date()407      this.project.generatedProjectIdTimestamp = timestamp408      const stub = sinon.stub()409      this.project.watchSettingsAndStartWebsockets({ onSettingsChanged: stub })410      // get the object passed to watchers.watch411      const obj = this.watch.getCall(0).args[1]412      obj.onChange()413      expect(stub).not.to.be.called414      // subtract 1 second from our timestamp415      timestamp.setSeconds(timestamp.getSeconds() - 1)416      obj.onChange()417      expect(stub).to.be.calledOnce418    })419  })420  context('#checkSupportFile', () => {421    beforeEach(function () {422      sinon.stub(fs, 'pathExists').resolves(true)423      this.project = new ProjectE2E('/_test-output/path/to/project-e2e')424      this.project.server = { onTestFileChange: sinon.spy() }425      sinon.stub(preprocessor, 'getFile').resolves()426      this.config = {427        projectRoot: '/path/to/root/',428        supportFile: '/path/to/root/foo/bar.js',429      }430    })431    it('does nothing when {supportFile: false}', function () {432      const ret = this.project.checkSupportFile({ supportFile: false })433      expect(ret).to.be.undefined434    })435    it('throws when support file does not exist', function () {436      fs.pathExists.resolves(false)437      return this.project.checkSupportFile(this.config)438      .catch((e) => {439        expect(e.message).to.include('The support file is missing or invalid.')440      })441    })442  })443  context('#watchPluginsFile', () => {444    beforeEach(function () {445      sinon.stub(fs, 'pathExists').resolves(true)446      this.project = new ProjectE2E('/_test-output/path/to/project-e2e')447      this.project.watchers = { watchTree: sinon.spy() }448      sinon.stub(plugins, 'init').resolves()449      this.config = {450        pluginsFile: '/path/to/plugins-file',451      }452    })453    it('does nothing when {pluginsFile: false}', function () {454      this.config.pluginsFile = false455      return this.project.watchPluginsFile(this.config, {}).then(() => {456        expect(this.project.watchers.watchTree).not.to.be.called457      })458    })459    it('does nothing if pluginsFile does not exist', function () {460      fs.pathExists.resolves(false)461      return this.project.watchPluginsFile(this.config, {}).then(() => {462        expect(this.project.watchers.watchTree).not.to.be.called463      })464    })465    it('does nothing if in run mode', function () {466      return this.project.watchPluginsFile(this.config, {467        isTextTerminal: true,468      }).then(() => {469        expect(this.project.watchers.watchTree).not.to.be.called470      })471    })472    it('watches the pluginsFile', function () {473      return this.project.watchPluginsFile(this.config, {}).then(() => {474        expect(this.project.watchers.watchTree).to.be.calledWith(this.config.pluginsFile)475        expect(this.project.watchers.watchTree.lastCall.args[1]).to.be.an('object')476        expect(this.project.watchers.watchTree.lastCall.args[1].onChange).to.be.a('function')477      })478    })479    it('calls plugins.init when file changes', function () {480      return this.project.watchPluginsFile(this.config, {}).then(() => {481        this.project.watchers.watchTree.firstCall.args[1].onChange()482        expect(plugins.init).to.be.calledWith(this.config)483      })484    })485    it('handles errors from calling plugins.init', function (done) {486      const error = { name: 'foo', message: 'foo' }487      plugins.init.rejects(error)488      this.project.watchPluginsFile(this.config, {489        onError (err) {490          expect(err).to.eql(error)491          done()492        },493      })494      .then(() => {495        this.project.watchers.watchTree.firstCall.args[1].onChange()496      })497    })498  })499  context('#watchSettingsAndStartWebsockets', () => {500    beforeEach(function () {501      this.project = new ProjectE2E('/_test-output/path/to/project-e2e')502      this.project.watchers = {}503      this.project.server = sinon.stub({ startWebsockets () {} })504      sinon.stub(this.project, 'watchSettings')505      sinon.stub(Automation, 'create').returns('automation')506    })507    it('calls server.startWebsockets with automation + config', function () {508      const c = {}509      this.project.watchSettingsAndStartWebsockets({}, c)510      expect(this.project.server.startWebsockets).to.be.calledWith('automation', c)511    })512    it('passes onReloadBrowser callback', function () {513      const fn = sinon.stub()514      this.project.server.startWebsockets.yieldsTo('onReloadBrowser')515      this.project.watchSettingsAndStartWebsockets({ onReloadBrowser: fn }, {})516      expect(fn).to.be.calledOnce517    })518  })519  context('#getProjectId', () => {520    beforeEach(function () {521      this.project = new ProjectE2E('/_test-output/path/to/project-e2e')522      this.verifyExistence = sinon.stub(ProjectE2E.prototype, 'verifyExistence').resolves()523    })524    it('calls verifyExistence', function () {525      sinon.stub(settings, 'read').resolves({ projectId: 'id-123' })526      return this.project.getProjectId()527      .then(() => expect(this.verifyExistence).to.be.calledOnce)528    })529    it('returns the project id from settings', function () {530      sinon.stub(settings, 'read').resolves({ projectId: 'id-123' })531      return this.project.getProjectId()532      .then((id) => expect(id).to.eq('id-123'))533    })534    it('throws NO_PROJECT_ID with the projectRoot when no projectId was found', function () {535      sinon.stub(settings, 'read').resolves({})536      return this.project.getProjectId()537      .then((id) => {538        throw new Error('expected to fail, but did not')539      }).catch((err) => {540        expect(err.type).to.eq('NO_PROJECT_ID')541        expect(err.message).to.include('/_test-output/path/to/project-e2e')542      })543    })544    it('bubbles up Settings.read errors', function () {545      const err = new Error()546      err.code = 'EACCES'547      sinon.stub(settings, 'read').rejects(err)548      return this.project.getProjectId()549      .then((id) => {550        throw new Error('expected to fail, but did not')551      }).catch((err) => {552        expect(err.code).to.eq('EACCES')553      })554    })555  })556  context('#writeProjectId', () => {557    beforeEach(function () {558      this.project = new ProjectE2E('/_test-output/path/to/project-e2e')559      sinon.stub(settings, 'write')560      .withArgs(this.project.projectRoot, { projectId: 'id-123' })561      .resolves({ projectId: 'id-123' })562    })563    it('calls Settings.write with projectRoot and attrs', function () {564      return this.project.writeProjectId('id-123').then((id) => {565        expect(id).to.eq('id-123')566      })567    })568    it('sets generatedProjectIdTimestamp', function () {569      return this.project.writeProjectId('id-123').then(() => {570        expect(this.project.generatedProjectIdTimestamp).to.be.a('date')571      })572    })573  })574  context('#getSpecUrl', () => {575    beforeEach(function () {576      this.project2 = new ProjectE2E(this.idsPath)577      return settings.write(this.idsPath, { port: 2020 })578    })579    it('returns fully qualified url when spec exists', function () {580      return this.project2.getSpecUrl('cypress/integration/bar.js')581      .then((str) => {582        expect(str).to.eq('http://localhost:2020/__/#/tests/integration/bar.js')583      })584    })585    it('returns fully qualified url on absolute path to spec', function () {586      const todosSpec = path.join(this.todosPath, 'tests/sub/sub_test.coffee')587      return this.project.getSpecUrl(todosSpec)588      .then((str) => {589        expect(str).to.eq('http://localhost:8888/__/#/tests/integration/sub/sub_test.coffee')590      })591    })592    it('escapses %, &', function () {593      const todosSpec = path.join(this.todosPath, 'tests/sub/a&b%c.js')594      return this.project.getSpecUrl(todosSpec)595      .then((str) => {596        expect(str).to.eq('http://localhost:8888/__/#/tests/integration/sub/a%26b%25c.js')597      })598    })599    // ? is invalid in Windows, but it can be tested here600    // because it's a unit test and doesn't check the existence of files601    it('escapes ?', function () {602      const todosSpec = path.join(this.todosPath, 'tests/sub/a?.spec.js')603      return this.project.getSpecUrl(todosSpec)604      .then((str) => {605        expect(str).to.eq('http://localhost:8888/__/#/tests/integration/sub/a%3F.spec.js')606      })607    })608    it('escapes %, &, ? in the url dir', function () {609      const todosSpec = path.join(this.todosPath, 'tests/s%&?ub/a.spec.js')610      return this.project.getSpecUrl(todosSpec)611      .then((str) => {612        expect(str).to.eq('http://localhost:8888/__/#/tests/integration/s%25%26%3Fub/a.spec.js')613      })614    })615    it('returns __all spec url', function () {616      return this.project.getSpecUrl()617      .then((str) => {618        expect(str).to.eq('http://localhost:8888/__/#/tests/__all')619      })620    })621    it('returns __all spec url with spec is __all', function () {622      return this.project.getSpecUrl('__all')623      .then((str) => {624        expect(str).to.eq('http://localhost:8888/__/#/tests/__all')625      })626    })627  })628  context('.add', () => {629    beforeEach(function () {630      this.pristinePath = Fixtures.projectPath('pristine')631    })632    it('inserts path into cache', function () {633      return ProjectE2E.add(this.pristinePath, {})634      .then(() => cache.read()).then((json) => {635        expect(json.PROJECTS).to.deep.eq([this.pristinePath])636      })637    })638    describe('if project at path has id', () => {639      it('returns object containing path and id', function () {640        sinon.stub(settings, 'read').resolves({ projectId: 'id-123' })641        return ProjectE2E.add(this.pristinePath, {})642        .then((project) => {643          expect(project.id).to.equal('id-123')644          expect(project.path).to.equal(this.pristinePath)645        })646      })647    })648    describe('if project at path does not have id', () => {649      it('returns object containing just the path', function () {650        sinon.stub(settings, 'read').rejects()651        return ProjectE2E.add(this.pristinePath, {})652        .then((project) => {653          expect(project.id).to.be.undefined654          expect(project.path).to.equal(this.pristinePath)655        })656      })657    })658    describe('if configFile is non-default', () => {659      it('doesn\'t cache anything and returns object containing just the path', function () {660        return ProjectE2E.add(this.pristinePath, { configFile: false })661        .then((project) => {662          expect(project.id).to.be.undefined663          expect(project.path).to.equal(this.pristinePath)664          return cache.read()665        }).then((json) => {666          expect(json.PROJECTS).to.deep.eq([])667        })668      })669    })670  })671  context('#createCiProject', () => {672    beforeEach(function () {673      this.project = new ProjectE2E('/_test-output/path/to/project-e2e')674      this.newProject = { id: 'project-id-123' }675      sinon.stub(this.project, 'writeProjectId').resolves('project-id-123')676      sinon.stub(user, 'ensureAuthToken').resolves('auth-token-123')677      sinon.stub(commitInfo, 'getRemoteOrigin').resolves('remoteOrigin')678      sinon.stub(api, 'createProject')679      .withArgs({ foo: 'bar' }, 'remoteOrigin', 'auth-token-123')680      .resolves(this.newProject)681    })682    it('calls api.createProject with user session', function () {683      return this.project.createCiProject({ foo: 'bar' }).then(() => {684        expect(api.createProject).to.be.calledWith({ foo: 'bar' }, 'remoteOrigin', 'auth-token-123')685      })686    })687    it('calls writeProjectId with id', function () {688      return this.project.createCiProject({ foo: 'bar' }).then(() => {689        expect(this.project.writeProjectId).to.be.calledWith('project-id-123')690      })691    })692    it('returns project id', function () {693      return this.project.createCiProject({ foo: 'bar' }).then((projectId) => {694        expect(projectId).to.eql(this.newProject)695      })696    })697  })698  context('#getRecordKeys', () => {699    beforeEach(function () {700      this.recordKeys = []701      this.project = new ProjectE2E(this.pristinePath)702      sinon.stub(settings, 'read').resolves({ projectId: 'id-123' })703      sinon.stub(user, 'ensureAuthToken').resolves('auth-token-123')704      sinon.stub(api, 'getProjectRecordKeys').resolves(this.recordKeys)705    })706    it('calls api.getProjectRecordKeys with project id + session', function () {707      return this.project.getRecordKeys().then(() => {708        expect(api.getProjectRecordKeys).to.be.calledWith('id-123', 'auth-token-123')709      })710    })711    it('returns ci keys', function () {712      return this.project.getRecordKeys().then((recordKeys) => {713        expect(recordKeys).to.equal(this.recordKeys)714      })715    })716  })717  context('#requestAccess', () => {718    beforeEach(function () {719      this.project = new ProjectE2E(this.pristinePath)720      sinon.stub(user, 'ensureAuthToken').resolves('auth-token-123')721      sinon.stub(api, 'requestAccess').resolves('response')722    })723    it('calls api.requestAccess with project id + auth token', function () {724      return this.project.requestAccess('project-id-123').then(() => {725        expect(api.requestAccess).to.be.calledWith('project-id-123', 'auth-token-123')726      })727    })728    it('returns response', function () {729      return this.project.requestAccess('project-id-123').then((response) => {730        expect(response).to.equal('response')731      })732    })733  })734  context('.remove', () => {735    beforeEach(() => {736      sinon.stub(cache, 'removeProject').resolves()737    })738    it('calls cache.removeProject with path', () => {739      return ProjectE2E.remove('/_test-output/path/to/project-e2e').then(() => {740        expect(cache.removeProject).to.be.calledWith('/_test-output/path/to/project-e2e')741      })742    })743  })744  context('.id', () => {745    it('returns project id', function () {746      return ProjectE2E.id(this.todosPath).then((id) => {747        expect(id).to.eq(this.projectId)748      })749    })750  })751  context('.getOrgs', () => {752    beforeEach(() => {753      sinon.stub(user, 'ensureAuthToken').resolves('auth-token-123')754      sinon.stub(api, 'getOrgs').resolves([])755    })756    it('calls api.getOrgs', () => {757      return ProjectE2E.getOrgs().then((orgs) => {758        expect(orgs).to.deep.eq([])759        expect(api.getOrgs).to.be.calledOnce760        expect(api.getOrgs).to.be.calledWith('auth-token-123')761      })762    })763  })764  context('.paths', () => {765    beforeEach(() => {766      sinon.stub(cache, 'getProjectRoots').resolves([])767    })768    it('calls cache.getProjectRoots', () => {769      return ProjectE2E.paths().then((ret) => {770        expect(ret).to.deep.eq([])771        expect(cache.getProjectRoots).to.be.calledOnce772      })773    })774  })775  context('.getPathsAndIds', () => {776    beforeEach(() => {777      sinon.stub(cache, 'getProjectRoots').resolves([778        '/path/to/first',779        '/path/to/second',780      ])781      sinon.stub(settings, 'id').resolves('id-123')782    })783    it('returns array of objects with paths and ids', () => {784      return ProjectE2E.getPathsAndIds().then((pathsAndIds) => {785        expect(pathsAndIds).to.eql([786          {787            path: '/path/to/first',788            id: 'id-123',789          },790          {791            path: '/path/to/second',792            id: 'id-123',793          },794        ])795      })796    })797  })798  context('.getProjectStatuses', () => {799    beforeEach(() => {800      sinon.stub(user, 'ensureAuthToken').resolves('auth-token-123')801    })802    it('gets projects from api', () => {803      sinon.stub(api, 'getProjects').resolves([])804      return ProjectE2E.getProjectStatuses([])805      .then(() => {806        expect(api.getProjects).to.have.been.calledWith('auth-token-123')807      })808    })809    it('returns array of projects', () => {810      sinon.stub(api, 'getProjects').resolves([])811      return ProjectE2E.getProjectStatuses([])812      .then((projectsWithStatuses) => {813        expect(projectsWithStatuses).to.eql([])814      })815    })816    it('returns same number as client projects, even if there are less api projects', () => {817      sinon.stub(api, 'getProjects').resolves([])818      return ProjectE2E.getProjectStatuses([{}])819      .then((projectsWithStatuses) => {820        expect(projectsWithStatuses.length).to.eql(1)821      })822    })823    it('returns same number as client projects, even if there are more api projects', () => {824      sinon.stub(api, 'getProjects').resolves([{}, {}])825      return ProjectE2E.getProjectStatuses([{}])826      .then((projectsWithStatuses) => {827        expect(projectsWithStatuses.length).to.eql(1)828      })829    })830    it('merges in details of matching projects', () => {831      sinon.stub(api, 'getProjects').resolves([832        { id: 'id-123', lastBuildStatus: 'passing' },833      ])834      return ProjectE2E.getProjectStatuses([{ id: 'id-123', path: '/_test-output/path/to/project' }])835      .then((projectsWithStatuses) => {836        expect(projectsWithStatuses[0]).to.eql({837          id: 'id-123',838          path: '/_test-output/path/to/project',839          lastBuildStatus: 'passing',840          state: 'VALID',841        })842      })843    })844    it('returns client project when it has no id', () => {845      sinon.stub(api, 'getProjects').resolves([])846      return ProjectE2E.getProjectStatuses([{ path: '/_test-output/path/to/project' }])847      .then((projectsWithStatuses) => {848        expect(projectsWithStatuses[0]).to.eql({849          path: '/_test-output/path/to/project',850          state: 'VALID',851        })852      })853    })854    describe('when client project has id and there is no matching user project', () => {855      beforeEach(() => {856        sinon.stub(api, 'getProjects').resolves([])857      })858      it('marks project as invalid if api 404s', () => {859        sinon.stub(api, 'getProject').rejects({ name: '', message: '', statusCode: 404 })860        return ProjectE2E.getProjectStatuses([{ id: 'id-123', path: '/_test-output/path/to/project' }])861        .then((projectsWithStatuses) => {862          expect(projectsWithStatuses[0]).to.eql({863            id: 'id-123',864            path: '/_test-output/path/to/project',865            state: 'INVALID',866          })867        })868      })869      it('marks project as unauthorized if api 403s', () => {870        sinon.stub(api, 'getProject').rejects({ name: '', message: '', statusCode: 403 })871        return ProjectE2E.getProjectStatuses([{ id: 'id-123', path: '/_test-output/path/to/project' }])872        .then((projectsWithStatuses) => {873          expect(projectsWithStatuses[0]).to.eql({874            id: 'id-123',875            path: '/_test-output/path/to/project',876            state: 'UNAUTHORIZED',877          })878        })879      })880      it('merges in project details and marks valid if somehow project exists and is authorized', () => {881        sinon.stub(api, 'getProject').resolves({ id: 'id-123', lastBuildStatus: 'passing' })882        return ProjectE2E.getProjectStatuses([{ id: 'id-123', path: '/_test-output/path/to/project' }])883        .then((projectsWithStatuses) => {884          expect(projectsWithStatuses[0]).to.eql({885            id: 'id-123',886            path: '/_test-output/path/to/project',887            lastBuildStatus: 'passing',888            state: 'VALID',889          })890        })891      })892      it('throws error if not accounted for', () => {893        const error = { name: '', message: '' }894        sinon.stub(api, 'getProject').rejects(error)895        return ProjectE2E.getProjectStatuses([{ id: 'id-123', path: '/_test-output/path/to/project' }])896        .then(() => {897          throw new Error('should have caught error but did not')898        }).catch((err) => {899          expect(err).to.equal(error)900        })901      })902    })903  })904  context('.getProjectStatus', () => {905    beforeEach(function () {906      this.clientProject = {907        id: 'id-123',908        path: '/_test-output/path/to/project',909      }910      sinon.stub(user, 'ensureAuthToken').resolves('auth-token-123')911    })912    it('gets project from api', function () {913      sinon.stub(api, 'getProject').resolves([])914      return ProjectE2E.getProjectStatus(this.clientProject)915      .then(() => {916        expect(api.getProject).to.have.been.calledWith('id-123', 'auth-token-123')917      })918    })919    it('returns project merged with details', function () {920      sinon.stub(api, 'getProject').resolves({921        lastBuildStatus: 'passing',922      })923      return ProjectE2E.getProjectStatus(this.clientProject)924      .then((project) => {925        expect(project).to.eql({926          id: 'id-123',927          path: '/_test-output/path/to/project',928          lastBuildStatus: 'passing',929          state: 'VALID',930        })931      })932    })933    it('returns project, marked as valid, if it does not have an id, without querying api', function () {934      sinon.stub(api, 'getProject')935      this.clientProject.id = undefined936      return ProjectE2E.getProjectStatus(this.clientProject)937      .then((project) => {938        expect(project).to.eql({939          id: undefined,940          path: '/_test-output/path/to/project',941          state: 'VALID',942        })943        expect(api.getProject).not.to.be.called944      })945    })946    it('marks project as invalid if api 404s', function () {947      sinon.stub(api, 'getProject').rejects({ name: '', message: '', statusCode: 404 })948      return ProjectE2E.getProjectStatus(this.clientProject)949      .then((project) => {950        expect(project).to.eql({951          id: 'id-123',952          path: '/_test-output/path/to/project',953          state: 'INVALID',954        })955      })956    })957    it('marks project as unauthorized if api 403s', function () {958      sinon.stub(api, 'getProject').rejects({ name: '', message: '', statusCode: 403 })959      return ProjectE2E.getProjectStatus(this.clientProject)960      .then((project) => {961        expect(project).to.eql({962          id: 'id-123',963          path: '/_test-output/path/to/project',964          state: 'UNAUTHORIZED',965        })966      })967    })968    it('throws error if not accounted for', function () {969      const error = { name: '', message: '' }970      sinon.stub(api, 'getProject').rejects(error)971      return ProjectE2E.getProjectStatus(this.clientProject)972      .then(() => {973        throw new Error('should have caught error but did not')974      }).catch((err) => {975        expect(err).to.equal(error)976      })977    })978  })979  context('.getSecretKeyByPath', () => {980    beforeEach(() => {981      sinon.stub(user, 'ensureAuthToken').resolves('auth-token-123')982    })983    it('calls api.getProjectToken with id + session', function () {984      sinon.stub(api, 'getProjectToken')985      .withArgs(this.projectId, 'auth-token-123')986      .resolves('key-123')987      return ProjectE2E.getSecretKeyByPath(this.todosPath).then((key) => {988        expect(key).to.eq('key-123')989      })990    })991    it('throws CANNOT_FETCH_PROJECT_TOKEN on error', function () {992      sinon.stub(api, 'getProjectToken')993      .withArgs(this.projectId, 'auth-token-123')994      .rejects(new Error())995      return ProjectE2E.getSecretKeyByPath(this.todosPath)996      .then(() => {997        throw new Error('should have caught error but did not')998      }).catch((err) => {999        expect(err.type).to.eq('CANNOT_FETCH_PROJECT_TOKEN')1000      })1001    })1002  })1003  context('.generateSecretKeyByPath', () => {1004    beforeEach(() => {1005      sinon.stub(user, 'ensureAuthToken').resolves('auth-token-123')1006    })1007    it('calls api.updateProjectToken with id + session', function () {1008      sinon.stub(api, 'updateProjectToken')1009      .withArgs(this.projectId, 'auth-token-123')1010      .resolves('new-key-123')1011      return ProjectE2E.generateSecretKeyByPath(this.todosPath).then((key) => {1012        expect(key).to.eq('new-key-123')1013      })1014    })1015    it('throws CANNOT_CREATE_PROJECT_TOKEN on error', function () {1016      sinon.stub(api, 'updateProjectToken')1017      .withArgs(this.projectId, 'auth-token-123')1018      .rejects(new Error())1019      return ProjectE2E.generateSecretKeyByPath(this.todosPath)1020      .then(() => {1021        throw new Error('should have caught error but did not')1022      }).catch((err) => {1023        expect(err.type).to.eq('CANNOT_CREATE_PROJECT_TOKEN')1024      })1025    })1026  })...

Full Screen

Full Screen

project.js

Source:project.js Github

copy

Full Screen

...122        }123      });124    };125    Project.prototype.getRuns = function() {126      return Promise.all([this.getProjectId(), user.ensureAuthToken()]).spread(function(projectId, authToken) {127        return api.getProjectRuns(projectId, authToken);128      });129    };130    Project.prototype.reset = function() {131      debug("resetting project instance %s", this.projectRoot);132      this.spec = this.browser = null;133      return Promise["try"]((function(_this) {134        return function() {135          var ref, ref1;136          if ((ref = _this.automation) != null) {137            ref.reset();138          }139          return (ref1 = _this.server) != null ? ref1.reset() : void 0;140        };141      })(this));142    };143    Project.prototype.close = function() {144      var ref, ref1;145      debug("closing project instance %s", this.projectRoot);146      if (this.memoryCheck) {147        clearInterval(this.memoryCheck);148      }149      this.cfg = this.spec = this.browser = null;150      return Promise.join((ref = this.server) != null ? ref.close() : void 0, (ref1 = this.watchers) != null ? ref1.close() : void 0, preprocessor.close()).then(function() {151        return process.chdir(localCwd);152      });153    };154    Project.prototype.checkSupportFile = function(cfg) {155      var supportFile;156      if (supportFile = cfg.supportFile) {157        return fs.pathExists(supportFile).then((function(_this) {158          return function(found) {159            if (!found) {160              return errors["throw"]("SUPPORT_FILE_NOT_FOUND", supportFile);161            }162          };163        })(this));164      }165    };166    Project.prototype.watchPluginsFile = function(cfg, options) {167      debug("attempt watch plugins file: " + cfg.pluginsFile);168      if (!cfg.pluginsFile) {169        return Promise.resolve();170      }171      return fs.pathExists(cfg.pluginsFile).then((function(_this) {172        return function(found) {173          debug("plugins file found? " + found);174          if (!found) {175            return;176          }177          debug("watch plugins file");178          return _this.watchers.watchTree(cfg.pluginsFile, {179            onChange: function() {180              debug("plugins file changed");181              return _this._initPlugins(cfg, options)["catch"](function(err) {182                return options.onError(err);183              });184            }185          });186        };187      })(this));188    };189    Project.prototype.watchSettings = function(onSettingsChanged) {190      var obj;191      if (!onSettingsChanged) {192        return;193      }194      debug("watch settings files");195      obj = {196        onChange: (function(_this) {197          return function(filePath, stats) {198            if (_this.generatedProjectIdTimestamp && (new Date - _this.generatedProjectIdTimestamp) < 1000) {199              return;200            }201            return onSettingsChanged.call(_this);202          };203        })(this)204      };205      this.watchers.watch(settings.pathToCypressJson(this.projectRoot), obj);206      return this.watchers.watch(settings.pathToCypressEnvJson(this.projectRoot), obj);207    };208    Project.prototype.watchSettingsAndStartWebsockets = function(options, cfg) {209      var err, errorMsg, paths, projectRoot, reporter;210      if (options == null) {211        options = {};212      }213      if (cfg == null) {214        cfg = {};215      }216      this.watchSettings(options.onSettingsChanged);217      reporter = cfg.reporter, projectRoot = cfg.projectRoot;218      if (cfg.report) {219        try {220          Reporter.loadReporter(reporter, projectRoot);221        } catch (error) {222          err = error;223          paths = Reporter.getSearchPathsForReporter(reporter, projectRoot);224          errorMsg = err.code === "MODULE_NOT_FOUND" ? err.message : err.stack;225          errors["throw"]("INVALID_REPORTER_NAME", {226            paths: paths,227            error: errorMsg,228            name: reporter229          });230        }231        reporter = Reporter.create(reporter, cfg.reporterOptions, projectRoot);232      }233      this.automation = Automation.create(cfg.namespace, cfg.socketIoCookie, cfg.screenshotsFolder);234      return this.server.startWebsockets(this.automation, cfg, {235        onReloadBrowser: options.onReloadBrowser,236        onFocusTests: options.onFocusTests,237        onSpecChanged: options.onSpecChanged,238        onSavedStateChanged: options.onSavedStateChanged,239        onConnect: (function(_this) {240          return function(id) {241            return _this.emit("socket:connected", id);242          };243        })(this),244        onSetRunnables: function(runnables) {245          debug("received runnables %o", runnables);246          return reporter != null ? reporter.setRunnables(runnables) : void 0;247        },248        onMocha: (function(_this) {249          return function(event, runnable) {250            debug("onMocha", event);251            if (!reporter) {252              return;253            }254            reporter.emit(event, runnable);255            if (event === "end") {256              return Promise.all([reporter != null ? reporter.end() : void 0, _this.server.end()]).spread(function(stats) {257                if (stats == null) {258                  stats = {};259                }260                return _this.emit("end", stats);261              });262            }263          };264        })(this)265      });266    };267    Project.prototype.changeToUrl = function(url) {268      return this.server.changeToUrl(url);269    };270    Project.prototype.setCurrentSpecAndBrowser = function(spec, browser) {271      this.spec = spec;272      return this.browser = browser;273    };274    Project.prototype.getCurrentSpecAndBrowser = function() {275      return _.pick(this, "spec", "browser");276    };277    Project.prototype.setBrowsers = function(browsers) {278      if (browsers == null) {279        browsers = [];280      }281      return this.getConfig().then(function(cfg) {282        return cfg.browsers = browsers;283      });284    };285    Project.prototype.getAutomation = function() {286      return this.automation;287    };288    Project.prototype.determineIsNewProject = function(folder) {289      return scaffold.isNewProject(folder);290    };291    Project.prototype.getConfig = function(options) {292      var setNewProject;293      if (options == null) {294        options = {};295      }296      if (this.cfg) {297        return Promise.resolve(this.cfg);298      }299      setNewProject = (function(_this) {300        return function(cfg) {301          if (cfg.isTextTerminal) {302            return;303          }304          if (!cfg.integrationFolder) {305            throw new Error("Missing integration folder");306          }307          return _this.determineIsNewProject(cfg.integrationFolder).then(function(untouchedScaffold) {308            var userHasSeenOnBoarding;309            userHasSeenOnBoarding = _.get(cfg, 'state.showedOnBoardingModal', false);310            scaffoldDebug("untouched scaffold " + untouchedScaffold + " modal closed " + userHasSeenOnBoarding);311            return cfg.isNewProject = untouchedScaffold && !userHasSeenOnBoarding;312          });313        };314      })(this);315      return config.get(this.projectRoot, options).then((function(_this) {316        return function(cfg) {317          return _this._setSavedState(cfg);318        };319      })(this)).tap(setNewProject);320    };321    Project.prototype.saveState = function(stateChanges) {322      var newState;323      if (stateChanges == null) {324        stateChanges = {};325      }326      if (!this.cfg) {327        throw new Error("Missing project config");328      }329      if (!this.projectRoot) {330        throw new Error("Missing project root");331      }332      newState = _.merge({}, this.cfg.state, stateChanges);333      return savedState(this.projectRoot, this.cfg.isTextTerminal).then(function(state) {334        return state.set(newState);335      }).then((function(_this) {336        return function() {337          _this.cfg.state = newState;338          return newState;339        };340      })(this));341    };342    Project.prototype._setSavedState = function(cfg) {343      debug("get saved state");344      return savedState(this.projectRoot, cfg.isTextTerminal).then(function(state) {345        return state.get();346      }).then(function(state) {347        cfg.state = state;348        return cfg;349      });350    };351    Project.prototype.getSpecUrl = function(absoluteSpecPath) {352      return this.getConfig().then((function(_this) {353        return function(cfg) {354          var prefixedPath;355          if (!absoluteSpecPath || (absoluteSpecPath === "__all")) {356            return _this.normalizeSpecUrl(cfg.browserUrl, "/__all");357          } else {358            prefixedPath = _this.getPrefixedPathToSpec(cfg, absoluteSpecPath);359            return _this.normalizeSpecUrl(cfg.browserUrl, prefixedPath);360          }361        };362      })(this));363    };364    Project.prototype.getPrefixedPathToSpec = function(cfg, pathToSpec, type) {365      var integrationFolder, projectRoot;366      if (type == null) {367        type = "integration";368      }369      integrationFolder = cfg.integrationFolder, projectRoot = cfg.projectRoot;370      return "/" + path.join(type, path.relative(integrationFolder, path.resolve(projectRoot, pathToSpec)));371    };372    Project.prototype.normalizeSpecUrl = function(browserUrl, specUrl) {373      var replacer;374      replacer = function(match, p1) {375        return match.replace("//", "/");376      };377      return [browserUrl, "#/tests", specUrl].join("/").replace(multipleForwardSlashesRe, replacer);378    };379    Project.prototype.scaffold = function(cfg) {380      var push, scaffolds;381      debug("scaffolding project %s", this.projectRoot);382      scaffolds = [];383      push = scaffolds.push.bind(scaffolds);384      push(scaffold.support(cfg.supportFolder, cfg));385      if (!cfg.isTextTerminal) {386        push(scaffold.integration(cfg.integrationFolder, cfg));387        push(scaffold.fixture(cfg.fixturesFolder, cfg));388      }389      return Promise.all(scaffolds);390    };391    Project.prototype.writeProjectId = function(id) {392      var attrs;393      attrs = {394        projectId: id395      };396      logger.info("Writing Project ID", _.clone(attrs));397      this.generatedProjectIdTimestamp = new Date;398      return settings.write(this.projectRoot, attrs)["return"](id);399    };400    Project.prototype.getProjectId = function() {401      return this.verifyExistence().then((function(_this) {402        return function() {403          return settings.read(_this.projectRoot);404        };405      })(this)).then((function(_this) {406        return function(settings) {407          var id;408          if (settings && (id = settings.projectId)) {409            return id;410          }411          return errors["throw"]("NO_PROJECT_ID", _this.projectRoot);412        };413      })(this));414    };415    Project.prototype.verifyExistence = function() {416      return fs.statAsync(this.projectRoot)["return"](this)["catch"]((function(_this) {417        return function() {418          return errors["throw"]("NO_PROJECT_FOUND_AT_PROJECT_ROOT", _this.projectRoot);419        };420      })(this));421    };422    Project.prototype.createCiProject = function(projectDetails) {423      return user.ensureAuthToken().then((function(_this) {424        return function(authToken) {425          return commitInfo.getRemoteOrigin(_this.projectRoot).then(function(remoteOrigin) {426            return api.createProject(projectDetails, remoteOrigin, authToken);427          });428        };429      })(this)).then((function(_this) {430        return function(newProject) {431          return _this.writeProjectId(newProject.id)["return"](newProject);432        };433      })(this));434    };435    Project.prototype.getRecordKeys = function() {436      return Promise.all([this.getProjectId(), user.ensureAuthToken()]).spread(function(projectId, authToken) {437        return api.getProjectRecordKeys(projectId, authToken);438      });439    };440    Project.prototype.requestAccess = function(projectId) {441      return user.ensureAuthToken().then(function(authToken) {442        return api.requestAccess(projectId, authToken);443      });444    };445    Project.getOrgs = function() {446      return user.ensureAuthToken().then(function(authToken) {447        return api.getOrgs(authToken);448      });449    };450    Project.paths = function() {451      return cache.getProjectRoots();452    };453    Project.getPathsAndIds = function() {454      return cache.getProjectRoots().map(function(projectRoot) {455        return Promise.props({456          path: projectRoot,457          id: settings.id(projectRoot)458        });459      });460    };461    Project._mergeDetails = function(clientProject, project) {462      return _.extend({}, clientProject, project, {463        state: "VALID"464      });465    };466    Project._mergeState = function(clientProject, state) {467      return _.extend({}, clientProject, {468        state: state469      });470    };471    Project._getProject = function(clientProject, authToken) {472      debug("get project from api", clientProject.id, clientProject.path);473      return api.getProject(clientProject.id, authToken).then(function(project) {474        debug("got project from api");475        return Project._mergeDetails(clientProject, project);476      })["catch"](function(err) {477        debug("failed to get project from api", err.statusCode);478        switch (err.statusCode) {479          case 404:480            return Project._mergeState(clientProject, "INVALID");481          case 403:482            return Project._mergeState(clientProject, "UNAUTHORIZED");483          default:484            throw err;485        }486      });487    };488    Project.getProjectStatuses = function(clientProjects) {489      if (clientProjects == null) {490        clientProjects = [];491      }492      debug("get project statuses for " + clientProjects.length + " projects");493      return user.ensureAuthToken().then(function(authToken) {494        debug("got auth token " + authToken);495        return api.getProjects(authToken).then(function(projects) {496          var projectsIndex;497          if (projects == null) {498            projects = [];499          }500          debug("got " + projects.length + " projects");501          projectsIndex = _.keyBy(projects, "id");502          return Promise.all(_.map(clientProjects, function(clientProject) {503            var project;504            debug("looking at", clientProject.path);505            if (!clientProject.id) {506              debug("no project id");507              return Project._mergeState(clientProject, "VALID");508            }509            if (project = projectsIndex[clientProject.id]) {510              debug("found matching:", project);511              return Project._mergeDetails(clientProject, project);512            } else {513              debug("did not find matching:", project);514              return Project._getProject(clientProject, authToken);515            }516          }));517        });518      });519    };520    Project.getProjectStatus = function(clientProject) {521      debug("get project status for", clientProject.id, clientProject.path);522      if (!clientProject.id) {523        debug("no project id");524        return Promise.resolve(Project._mergeState(clientProject, "VALID"));525      }526      return user.ensureAuthToken().then(function(authToken) {527        debug("got auth token " + authToken);528        return Project._getProject(clientProject, authToken);529      });530    };531    Project.remove = function(path) {532      return cache.removeProject(path);533    };534    Project.add = function(path) {535      return cache.insertProject(path).then((function(_this) {536        return function() {537          return _this.id(path);538        };539      })(this)).then(function(id) {540        return {541          id: id,542          path: path543        };544      })["catch"](function() {545        return {546          path: path547        };548      });549    };550    Project.id = function(path) {551      return Project(path).getProjectId();552    };553    Project.ensureExists = function(path) {554      return settings.exists(path);555    };556    Project.config = function(path) {557      return Project(path).getConfig();558    };559    Project.getSecretKeyByPath = function(path) {560      return Project.id(path).then(function(id) {561        return user.ensureAuthToken().then(function(authToken) {562          return api.getProjectToken(id, authToken)["catch"](function() {563            return errors["throw"]("CANNOT_FETCH_PROJECT_TOKEN");564          });565        });566      });567    };568    Project.generateSecretKeyByPath = function(path) {569      return Project.id(path).then(function(id) {570        return user.ensureAuthToken().then(function(authToken) {571          return api.updateProjectToken(id, authToken)["catch"](function() {572            return errors["throw"]("CANNOT_CREATE_PROJECT_TOKEN");573          });574        });575      });576    };577    Project.findSpecs = function(projectRoot, specPattern) {578      debug("finding specs for project %s", projectRoot);579      la(check.unemptyString(projectRoot), "missing project path", projectRoot);580      la(check.maybe.unemptyString(specPattern), "invalid spec pattern", specPattern);581      if (specPattern) {582        specPattern = path.resolve(projectRoot, specPattern);583      }584      return Project(projectRoot).getConfig().then(function(cfg) {...

Full Screen

Full Screen

user_spec.js

Source:user_spec.js Github

copy

Full Screen

...69  })70  context('.ensureAuthToken', () => {71    it('returns authToken', () => {72      sinon.stub(cache, 'getUser').resolves({ name: 'brian', authToken: 'abc-123' })73      return user.ensureAuthToken().then((st) => {74        expect(st).to.eq('abc-123')75      })76    })77    it('throws NOT_LOGGED_IN when no authToken, tagged as api error', () => {78      sinon.stub(cache, 'getUser').resolves(null)79      return user.ensureAuthToken()80      .then(() => {81        throw new Error('should have thrown an error')82      }).catch((err) => {83        const expectedErr = errors.get('NOT_LOGGED_IN')84        expect(err.message).to.eq(expectedErr.message)85        expect(err.isApiError).to.be.true86        expect(err.type).to.eq(expectedErr.type)87      })88    })89  })...

Full Screen

Full Screen

user.js

Source:user.js Github

copy

Full Screen

1const debug = require('debug')('cypress:server:user')2const api = require('./api')3const cache = require('./cache')4const errors = require('./errors')5const keys = require('./util/keys')6module.exports = {7  get () {8    return cache.getUser()9  },10  getSafely () {11    return this.get()12    .tap((user) => {13      if (user.authToken) {14        user.authToken = keys.hide(user.authToken)15      }16    })17  },18  set (user) {19    return cache.setUser(user)20  },21  getBaseLoginUrl () {22    return api.getAuthUrls()23    .get('dashboardAuthUrl')24  },25  logOut () {26    return this.get().then((user) => {27      const authToken = user && user.authToken28      return cache.removeUser().then(() => {29        if (authToken) {30          return api.postLogout(authToken)31        }32      })33    })34  },35  syncProfile (authToken) {36    debug('synchronizing user profile')37    return api.getMe(authToken)38    .then((res) => {39      debug('received /me %o', res)40      const user = {41        authToken,42        name: res.name,43        email: res.email,44      }45      return this.set(user)46      .return(user)47    })48  },49  ensureAuthToken () {50    return this.get().then((user) => {51      // return authToken if we have one52      let at53      if (user && (at = user.authToken)) {54        debug('found authToken %s', at)55        return at56      }57      // else throw the not logged in error58      const error = errors.get('NOT_LOGGED_IN')59      // tag it as api error since the user is only relevant60      // in regards to the api61      error.isApiError = true62      throw error63    })64  },...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1Cypress.Commands.add('login', (email, password) => {2  cy.request({3    body: {4    }5  }).then((response) => {6    window.localStorage.setItem('authToken', response.body.token);7  });8});9Cypress.Commands.add('logout', () => {10  cy.request({11  }).then(() => {12    window.localStorage.removeItem('authToken');13  });14});15describe('My First Test', function() {16  it('Does not do much!', function() {17  });18});19describe('My First Test', function() {20  it('Does not do much!', function() {21  });22  it('Logs in', function() {23    cy.login('

Full Screen

Cypress Tutorial

Cypress is a renowned Javascript-based open-source, easy-to-use end-to-end testing framework primarily used for testing web applications. Cypress is a relatively new player in the automation testing space and has been gaining much traction lately, as evidenced by the number of Forks (2.7K) and Stars (42.1K) for the project. LambdaTest’s Cypress Tutorial covers step-by-step guides that will help you learn from the basics till you run automation tests on LambdaTest.

Chapters:

  1. What is Cypress? -
  2. Why Cypress? - Learn why Cypress might be a good choice for testing your web applications.
  3. Features of Cypress Testing - Learn about features that make Cypress a powerful and flexible tool for testing web applications.
  4. Cypress Drawbacks - Although Cypress has many strengths, it has a few limitations that you should be aware of.
  5. Cypress Architecture - Learn more about Cypress architecture and how it is designed to be run directly in the browser, i.e., it does not have any additional servers.
  6. Browsers Supported by Cypress - Cypress is built on top of the Electron browser, supporting all modern web browsers. Learn browsers that support Cypress.
  7. Selenium vs Cypress: A Detailed Comparison - Compare and explore some key differences in terms of their design and features.
  8. Cypress Learning: Best Practices - Take a deep dive into some of the best practices you should use to avoid anti-patterns in your automation tests.
  9. How To Run Cypress Tests on LambdaTest? - Set up a LambdaTest account, and now you are all set to learn how to run Cypress tests.

Certification

You can elevate your expertise with end-to-end testing using the Cypress automation framework and stay one step ahead in your career by earning a Cypress certification. Check out our Cypress 101 Certification.

YouTube

Watch this 3 hours of complete tutorial to learn the basics of Cypress and various Cypress commands with the Cypress testing at LambdaTest.

Run Cypress automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful