/// <reference types="cypress" />

context('Cypress.Commands', () => {
  beforeEach(() => {
    cy.visit('https://example.cypress.io/cypress-api')
  })

  // https://on.cypress.io/custom-commands

  it('.add() - create a custom command', () => {
    Cypress.Commands.add('console', {
      prevSubject: true,
    }, (subject, method) => {
      // Otrzymujemy automatycznie poprzedni podmiot (subject)
      // i zmieniane są argumenty poleceń

      // Pozwala nam zmienić używaną metodę konsoli
      method = method || 'log'

      // Rejestrujemy podmiot w konsoli
      // @ts-ignore TS7017
      console[method]('The subject is', subject)

      // Cokolwiek zwracamy staje się nowym podmiotem
      // Nie chcemy zmieniać podmiotu,
      // więc zwracamy to, co zostało przekazane
      return subject
    })

    // @ts-ignore TS2339
    cy.get('button').console('info').then(($button) => {
      // Podmiotem jest wciąż $button
    })
  })
})

context('Cypress.Cookies', () => {
  beforeEach(() => {
    cy.visit('https://example.cypress.io/cypress-api')
  })

  // https://on.cypress.io/cookies
  it('.debug() - enable or disable debugging', () => {
    Cypress.Cookies.debug(true)

    // Cypress będzie teraz rejestrował w konsoli,
    // gdy pliki cookie nie zostaną ustawione lub wyczyszczone
    cy.setCookie('fakeCookie', '123ABC')
    cy.clearCookie('fakeCookie')
    cy.setCookie('fakeCookie', '123ABC')
    cy.clearCookie('fakeCookie')
    cy.setCookie('fakeCookie', '123ABC')
  })

  it('.preserveOnce() - preserve cookies by key', () => {
    // Standardowo pliki cookie są resetowane po każdym teście
    cy.getCookie('fakeCookie').should('not.be.ok')

    // Zachowanie pliku cookie spowoduje, że nie zostanie
    // on wyczyszczony, gdy rozpocznie się następny test
    cy.setCookie('lastCookie', '789XYZ')
    Cypress.Cookies.preserveOnce('lastCookie')
  })

  it('.defaults() - set defaults for all cookies', () => {
    // Teraz pliki cookie z nazwą 'session_id' nie będą 
    // czyszczone przed uruchomieniem nowego testu
    Cypress.Cookies.defaults({
      preserve: 'session_id',
    })
  })
})

context('Cypress.arch', () => {
  beforeEach(() => {
    cy.visit('https://example.cypress.io/cypress-api')
  })

  it('Get CPU architecture name of underlying OS', () => {
    // https://on.cypress.io/arch
    expect(Cypress.arch).to.exist
  })
})

context('Cypress.config()', () => {
  beforeEach(() => {
    cy.visit('https://example.cypress.io/cypress-api')
  })

  it('Get and set configuration options', () => {
    // https://on.cypress.io/config
    let myConfig = Cypress.config()

    expect(myConfig).to.have.property('animationDistanceThreshold', 5)
    expect(myConfig).to.have.property('baseUrl', null)
    expect(myConfig).to.have.property('defaultCommandTimeout', 4000)
    expect(myConfig).to.have.property('requestTimeout', 5000)
    expect(myConfig).to.have.property('responseTimeout', 30000)
    expect(myConfig).to.have.property('viewportHeight', 660)
    expect(myConfig).to.have.property('viewportWidth', 1000)
    expect(myConfig).to.have.property('pageLoadTimeout', 60000)
    expect(myConfig).to.have.property('waitForAnimations', true)

    expect(Cypress.config('pageLoadTimeout')).to.eq(60000)

    // To spowoduje zmianę konfiguracji reszty Twoich testów!
    Cypress.config('pageLoadTimeout', 20000)

    expect(Cypress.config('pageLoadTimeout')).to.eq(20000)

    Cypress.config('pageLoadTimeout', 60000)
  })
})

context('Cypress.dom', () => {
  beforeEach(() => {
    cy.visit('https://example.cypress.io/cypress-api')
  })

  // https://on.cypress.io/dom
  it('.isHidden() - determine if a DOM element is hidden', () => {
    let hiddenP = Cypress.$('.dom-p p.hidden').get(0)
    let visibleP = Cypress.$('.dom-p p.visible').get(0)

    // Nasz pierwszy paragraf ma klasę 'hidden'
    expect(Cypress.dom.isHidden(hiddenP)).to.be.true
    expect(Cypress.dom.isHidden(visibleP)).to.be.false
  })
})

context('Cypress.env()', () => {
  beforeEach(() => {
    cy.visit('https://example.cypress.io/cypress-api')
  })

  // Dla bardzo dynamicznych wartości możemy skonfigurować zmienne środowiskowe

  // https://on.cypress.io/environment-variables
  it('Get environment variables', () => {
    // https://on.cypress.io/env
    // Ustawiamy zmienne środowiskowe
    Cypress.env({
      host: 'veronica.dev.local',
      api_server: 'http://localhost:8888/v1/',
    })

    // Pobieramy zmienną środowiskową
    expect(Cypress.env('host')).to.eq('veronica.dev.local')

    // Ustawiamy zmienną środowiskową
    Cypress.env('api_server', 'http://localhost:8888/v2/')
    expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/')

    // Pobieramy wszystkie zmienne środowiskowe
    expect(Cypress.env()).to.have.property('host', 'veronica.dev.local')
    expect(Cypress.env()).to.have.property('api_server', 'http://localhost:8888/v2/')
  })
})

context('Cypress.log', () => {
  beforeEach(() => {
    cy.visit('https://example.cypress.io/cypress-api')
  })

  it('Control what is printed to the Command Log', () => {
    // https://on.cypress.io/cypress-log
  })
})

context('Cypress.platform', () => {
  beforeEach(() => {
    cy.visit('https://example.cypress.io/cypress-api')
  })

  it('Get underlying OS name', () => {
    // https://on.cypress.io/platform
    expect(Cypress.platform).to.be.exist
  })
})

context('Cypress.version', () => {
  beforeEach(() => {
    cy.visit('https://example.cypress.io/cypress-api')
  })

  it('Get current version of Cypress being run', () => {
    // https://on.cypress.io/version
    expect(Cypress.version).to.be.exist
  })
})

context('Cypress.spec', () => {
  beforeEach(() => {
    cy.visit('https://example.cypress.io/cypress-api')
  })

  it('Get current spec information', () => {
    // https://on.cypress.io/spec
    // Opakowujemy ten obiekt, aby można było go łatwo zbadać przez kliknięcie w dzienniku poleceń
    cy.wrap(Cypress.spec).should('include.keys', ['name', 'relative', 'absolute'])
  })
})
