mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-11-04 04:44:08 +01:00 
			
		
		
		
	getting there
This commit is contained in:
		
							
								
								
									
										10
									
								
								cypress/.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								cypress/.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
{
 | 
			
		||||
	"env": {
 | 
			
		||||
		"cypress/globals": true
 | 
			
		||||
	},
 | 
			
		||||
	"extends": ["plugin:cypress/recommended"],
 | 
			
		||||
	"plugins": ["cypress"],
 | 
			
		||||
	"rules":{
 | 
			
		||||
		"cypress/no-unnecessary-waiting": 0 
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -2,15 +2,16 @@
 | 
			
		||||
 | 
			
		||||
context('Actions', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/actions')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/actions');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // https://on.cypress.io/interacting-with-elements
 | 
			
		||||
 | 
			
		||||
  it('.type() - type into a DOM element', () => {
 | 
			
		||||
    // https://on.cypress.io/type
 | 
			
		||||
    cy.get('.action-email')
 | 
			
		||||
      .type('fake@email.com').should('have.value', 'fake@email.com')
 | 
			
		||||
      .type('fake@email.com')
 | 
			
		||||
      .should('have.value', 'fake@email.com')
 | 
			
		||||
 | 
			
		||||
      // .type() with special character sequences
 | 
			
		||||
      .type('{leftarrow}{rightarrow}{uparrow}{downarrow}')
 | 
			
		||||
@@ -24,48 +25,52 @@ context('Actions', () => {
 | 
			
		||||
 | 
			
		||||
      // Delay each keypress by 0.1 sec
 | 
			
		||||
      .type('slow.typing@email.com', { delay: 100 })
 | 
			
		||||
      .should('have.value', 'slow.typing@email.com')
 | 
			
		||||
      .should('have.value', 'slow.typing@email.com');
 | 
			
		||||
 | 
			
		||||
    cy.get('.action-disabled')
 | 
			
		||||
      // Ignore error checking prior to type
 | 
			
		||||
      // like whether the input is visible or disabled
 | 
			
		||||
      .type('disabled error checking', { force: true })
 | 
			
		||||
      .should('have.value', 'disabled error checking')
 | 
			
		||||
  })
 | 
			
		||||
      .should('have.value', 'disabled error checking');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.focus() - focus on a DOM element', () => {
 | 
			
		||||
    // https://on.cypress.io/focus
 | 
			
		||||
    cy.get('.action-focus').focus()
 | 
			
		||||
    cy.get('.action-focus')
 | 
			
		||||
      .focus()
 | 
			
		||||
      .should('have.class', 'focus')
 | 
			
		||||
      .prev().should('have.attr', 'style', 'color: orange;')
 | 
			
		||||
  })
 | 
			
		||||
      .prev()
 | 
			
		||||
      .should('have.attr', 'style', 'color: orange;');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.blur() - blur off a DOM element', () => {
 | 
			
		||||
    // https://on.cypress.io/blur
 | 
			
		||||
    cy.get('.action-blur').type('About to blur').blur()
 | 
			
		||||
    cy.get('.action-blur')
 | 
			
		||||
      .type('About to blur')
 | 
			
		||||
      .blur()
 | 
			
		||||
      .should('have.class', 'error')
 | 
			
		||||
      .prev().should('have.attr', 'style', 'color: red;')
 | 
			
		||||
  })
 | 
			
		||||
      .prev()
 | 
			
		||||
      .should('have.attr', 'style', 'color: red;');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.clear() - clears an input or textarea element', () => {
 | 
			
		||||
    // https://on.cypress.io/clear
 | 
			
		||||
    cy.get('.action-clear').type('Clear this text')
 | 
			
		||||
    cy.get('.action-clear')
 | 
			
		||||
      .type('Clear this text')
 | 
			
		||||
      .should('have.value', 'Clear this text')
 | 
			
		||||
      .clear()
 | 
			
		||||
      .should('have.value', '')
 | 
			
		||||
  })
 | 
			
		||||
      .should('have.value', '');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.submit() - submit a form', () => {
 | 
			
		||||
    // https://on.cypress.io/submit
 | 
			
		||||
    cy.get('.action-form')
 | 
			
		||||
      .find('[type="text"]').type('HALFOFF')
 | 
			
		||||
    cy.get('.action-form').submit()
 | 
			
		||||
      .next().should('contain', 'Your form has been submitted!')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.action-form').find('[type="text"]').type('HALFOFF');
 | 
			
		||||
    cy.get('.action-form').submit().next().should('contain', 'Your form has been submitted!');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.click() - click on a DOM element', () => {
 | 
			
		||||
    // https://on.cypress.io/click
 | 
			
		||||
    cy.get('.action-btn').click()
 | 
			
		||||
    cy.get('.action-btn').click();
 | 
			
		||||
 | 
			
		||||
    // You can click on 9 specific positions of an element:
 | 
			
		||||
    //  -----------------------------------
 | 
			
		||||
@@ -81,16 +86,16 @@ context('Actions', () => {
 | 
			
		||||
    //  -----------------------------------
 | 
			
		||||
 | 
			
		||||
    // clicking in the center of the element is the default
 | 
			
		||||
    cy.get('#action-canvas').click()
 | 
			
		||||
    cy.get('#action-canvas').click();
 | 
			
		||||
 | 
			
		||||
    cy.get('#action-canvas').click('topLeft')
 | 
			
		||||
    cy.get('#action-canvas').click('top')
 | 
			
		||||
    cy.get('#action-canvas').click('topRight')
 | 
			
		||||
    cy.get('#action-canvas').click('left')
 | 
			
		||||
    cy.get('#action-canvas').click('right')
 | 
			
		||||
    cy.get('#action-canvas').click('bottomLeft')
 | 
			
		||||
    cy.get('#action-canvas').click('bottom')
 | 
			
		||||
    cy.get('#action-canvas').click('bottomRight')
 | 
			
		||||
    cy.get('#action-canvas').click('topLeft');
 | 
			
		||||
    cy.get('#action-canvas').click('top');
 | 
			
		||||
    cy.get('#action-canvas').click('topRight');
 | 
			
		||||
    cy.get('#action-canvas').click('left');
 | 
			
		||||
    cy.get('#action-canvas').click('right');
 | 
			
		||||
    cy.get('#action-canvas').click('bottomLeft');
 | 
			
		||||
    cy.get('#action-canvas').click('bottom');
 | 
			
		||||
    cy.get('#action-canvas').click('bottomRight');
 | 
			
		||||
 | 
			
		||||
    // .click() accepts an x and y coordinate
 | 
			
		||||
    // that controls where the click occurs :)
 | 
			
		||||
@@ -102,90 +107,83 @@ context('Actions', () => {
 | 
			
		||||
      .click(100, 185)
 | 
			
		||||
      .click(125, 190)
 | 
			
		||||
      .click(150, 185)
 | 
			
		||||
      .click(170, 165)
 | 
			
		||||
      .click(170, 165);
 | 
			
		||||
 | 
			
		||||
    // click multiple elements by passing multiple: true
 | 
			
		||||
    cy.get('.action-labels>.label').click({ multiple: true })
 | 
			
		||||
    cy.get('.action-labels>.label').click({ multiple: true });
 | 
			
		||||
 | 
			
		||||
    // Ignore error checking prior to clicking
 | 
			
		||||
    cy.get('.action-opacity>.btn').click({ force: true })
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.action-opacity>.btn').click({ force: true });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.dblclick() - double click on a DOM element', () => {
 | 
			
		||||
    // https://on.cypress.io/dblclick
 | 
			
		||||
 | 
			
		||||
    // Our app has a listener on 'dblclick' event in our 'scripts.js'
 | 
			
		||||
    // that hides the div and shows an input on double click
 | 
			
		||||
    cy.get('.action-div').dblclick().should('not.be.visible')
 | 
			
		||||
    cy.get('.action-input-hidden').should('be.visible')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.action-div').dblclick().should('not.be.visible');
 | 
			
		||||
    cy.get('.action-input-hidden').should('be.visible');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.check() - check a checkbox or radio element', () => {
 | 
			
		||||
    // https://on.cypress.io/check
 | 
			
		||||
 | 
			
		||||
    // By default, .check() will check all
 | 
			
		||||
    // matching checkbox or radio elements in succession, one after another
 | 
			
		||||
    cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]')
 | 
			
		||||
      .check().should('be.checked')
 | 
			
		||||
    cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]').check().should('be.checked');
 | 
			
		||||
 | 
			
		||||
    cy.get('.action-radios [type="radio"]').not('[disabled]')
 | 
			
		||||
      .check().should('be.checked')
 | 
			
		||||
    cy.get('.action-radios [type="radio"]').not('[disabled]').check().should('be.checked');
 | 
			
		||||
 | 
			
		||||
    // .check() accepts a value argument
 | 
			
		||||
    cy.get('.action-radios [type="radio"]')
 | 
			
		||||
      .check('radio1').should('be.checked')
 | 
			
		||||
    cy.get('.action-radios [type="radio"]').check('radio1').should('be.checked');
 | 
			
		||||
 | 
			
		||||
    // .check() accepts an array of values
 | 
			
		||||
    cy.get('.action-multiple-checkboxes [type="checkbox"]')
 | 
			
		||||
      .check(['checkbox1', 'checkbox2']).should('be.checked')
 | 
			
		||||
      .check(['checkbox1', 'checkbox2'])
 | 
			
		||||
      .should('be.checked');
 | 
			
		||||
 | 
			
		||||
    // Ignore error checking prior to checking
 | 
			
		||||
    cy.get('.action-checkboxes [disabled]')
 | 
			
		||||
      .check({ force: true }).should('be.checked')
 | 
			
		||||
    cy.get('.action-checkboxes [disabled]').check({ force: true }).should('be.checked');
 | 
			
		||||
 | 
			
		||||
    cy.get('.action-radios [type="radio"]')
 | 
			
		||||
      .check('radio3', { force: true }).should('be.checked')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.action-radios [type="radio"]').check('radio3', { force: true }).should('be.checked');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.uncheck() - uncheck a checkbox element', () => {
 | 
			
		||||
    // https://on.cypress.io/uncheck
 | 
			
		||||
 | 
			
		||||
    // By default, .uncheck() will uncheck all matching
 | 
			
		||||
    // checkbox elements in succession, one after another
 | 
			
		||||
    cy.get('.action-check [type="checkbox"]')
 | 
			
		||||
      .not('[disabled]')
 | 
			
		||||
      .uncheck().should('not.be.checked')
 | 
			
		||||
    cy.get('.action-check [type="checkbox"]').not('[disabled]').uncheck().should('not.be.checked');
 | 
			
		||||
 | 
			
		||||
    // .uncheck() accepts a value argument
 | 
			
		||||
    cy.get('.action-check [type="checkbox"]')
 | 
			
		||||
      .check('checkbox1')
 | 
			
		||||
      .uncheck('checkbox1').should('not.be.checked')
 | 
			
		||||
      .uncheck('checkbox1')
 | 
			
		||||
      .should('not.be.checked');
 | 
			
		||||
 | 
			
		||||
    // .uncheck() accepts an array of values
 | 
			
		||||
    cy.get('.action-check [type="checkbox"]')
 | 
			
		||||
      .check(['checkbox1', 'checkbox3'])
 | 
			
		||||
      .uncheck(['checkbox1', 'checkbox3']).should('not.be.checked')
 | 
			
		||||
      .uncheck(['checkbox1', 'checkbox3'])
 | 
			
		||||
      .should('not.be.checked');
 | 
			
		||||
 | 
			
		||||
    // Ignore error checking prior to unchecking
 | 
			
		||||
    cy.get('.action-check [disabled]')
 | 
			
		||||
      .uncheck({ force: true }).should('not.be.checked')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.action-check [disabled]').uncheck({ force: true }).should('not.be.checked');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.select() - select an option in a <select> element', () => {
 | 
			
		||||
    // https://on.cypress.io/select
 | 
			
		||||
 | 
			
		||||
    // Select option(s) with matching text content
 | 
			
		||||
    cy.get('.action-select').select('apples')
 | 
			
		||||
    cy.get('.action-select').select('apples');
 | 
			
		||||
 | 
			
		||||
    cy.get('.action-select-multiple')
 | 
			
		||||
    .select(['apples', 'oranges', 'bananas'])
 | 
			
		||||
    cy.get('.action-select-multiple').select(['apples', 'oranges', 'bananas']);
 | 
			
		||||
 | 
			
		||||
    // Select option(s) with matching value
 | 
			
		||||
    cy.get('.action-select').select('fr-bananas')
 | 
			
		||||
    cy.get('.action-select').select('fr-bananas');
 | 
			
		||||
 | 
			
		||||
    cy.get('.action-select-multiple')
 | 
			
		||||
      .select(['fr-apples', 'fr-oranges', 'fr-bananas'])
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.action-select-multiple').select(['fr-apples', 'fr-oranges', 'fr-bananas']);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.scrollIntoView() - scroll an element into view', () => {
 | 
			
		||||
    // https://on.cypress.io/scrollintoview
 | 
			
		||||
@@ -194,27 +192,21 @@ context('Actions', () => {
 | 
			
		||||
    // because they're not within
 | 
			
		||||
    // the viewable area of their parent
 | 
			
		||||
    // (we need to scroll to see them)
 | 
			
		||||
    cy.get('#scroll-horizontal button')
 | 
			
		||||
      .should('not.be.visible')
 | 
			
		||||
    cy.get('#scroll-horizontal button').should('not.be.visible');
 | 
			
		||||
 | 
			
		||||
    // scroll the button into view, as if the user had scrolled
 | 
			
		||||
    cy.get('#scroll-horizontal button').scrollIntoView()
 | 
			
		||||
      .should('be.visible')
 | 
			
		||||
    cy.get('#scroll-horizontal button').scrollIntoView().should('be.visible');
 | 
			
		||||
 | 
			
		||||
    cy.get('#scroll-vertical button')
 | 
			
		||||
      .should('not.be.visible')
 | 
			
		||||
    cy.get('#scroll-vertical button').should('not.be.visible');
 | 
			
		||||
 | 
			
		||||
    // Cypress handles the scroll direction needed
 | 
			
		||||
    cy.get('#scroll-vertical button').scrollIntoView()
 | 
			
		||||
      .should('be.visible')
 | 
			
		||||
    cy.get('#scroll-vertical button').scrollIntoView().should('be.visible');
 | 
			
		||||
 | 
			
		||||
    cy.get('#scroll-both button')
 | 
			
		||||
      .should('not.be.visible')
 | 
			
		||||
    cy.get('#scroll-both button').should('not.be.visible');
 | 
			
		||||
 | 
			
		||||
    // Cypress knows to scroll to the right and down
 | 
			
		||||
    cy.get('#scroll-both button').scrollIntoView()
 | 
			
		||||
      .should('be.visible')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('#scroll-both button').scrollIntoView().should('be.visible');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.trigger() - trigger an event on a DOM element', () => {
 | 
			
		||||
    // https://on.cypress.io/trigger
 | 
			
		||||
@@ -228,12 +220,12 @@ context('Actions', () => {
 | 
			
		||||
    cy.get('.trigger-input-range')
 | 
			
		||||
      .invoke('val', 25)
 | 
			
		||||
      .trigger('change')
 | 
			
		||||
      .get('input[type=range]').siblings('p')
 | 
			
		||||
      .should('have.text', '25')
 | 
			
		||||
  })
 | 
			
		||||
      .get('input[type=range]')
 | 
			
		||||
      .siblings('p')
 | 
			
		||||
      .should('have.text', '25');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.scrollTo() - scroll the window or element to a position', () => {
 | 
			
		||||
 | 
			
		||||
    // https://on.cypress.io/scrollTo
 | 
			
		||||
 | 
			
		||||
    // You can scroll to 9 specific positions of an element:
 | 
			
		||||
@@ -251,22 +243,22 @@ context('Actions', () => {
 | 
			
		||||
 | 
			
		||||
    // if you chain .scrollTo() off of cy, we will
 | 
			
		||||
    // scroll the entire window
 | 
			
		||||
    cy.scrollTo('bottom')
 | 
			
		||||
    cy.scrollTo('bottom');
 | 
			
		||||
 | 
			
		||||
    cy.get('#scrollable-horizontal').scrollTo('right')
 | 
			
		||||
    cy.get('#scrollable-horizontal').scrollTo('right');
 | 
			
		||||
 | 
			
		||||
    // or you can scroll to a specific coordinate:
 | 
			
		||||
    // (x axis, y axis) in pixels
 | 
			
		||||
    cy.get('#scrollable-vertical').scrollTo(250, 250)
 | 
			
		||||
    cy.get('#scrollable-vertical').scrollTo(250, 250);
 | 
			
		||||
 | 
			
		||||
    // or you can scroll to a specific percentage
 | 
			
		||||
    // of the (width, height) of the element
 | 
			
		||||
    cy.get('#scrollable-both').scrollTo('75%', '25%')
 | 
			
		||||
    cy.get('#scrollable-both').scrollTo('75%', '25%');
 | 
			
		||||
 | 
			
		||||
    // control the easing of the scroll (default is 'swing')
 | 
			
		||||
    cy.get('#scrollable-vertical').scrollTo('center', { easing: 'linear' })
 | 
			
		||||
    cy.get('#scrollable-vertical').scrollTo('center', { easing: 'linear' });
 | 
			
		||||
 | 
			
		||||
    // control the duration of the scroll (in ms)
 | 
			
		||||
    cy.get('#scrollable-both').scrollTo('center', { duration: 2000 })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    cy.get('#scrollable-both').scrollTo('center', { duration: 2000 });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,8 @@
 | 
			
		||||
 | 
			
		||||
context('Aliasing', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/aliasing')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/aliasing');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.as() - alias a DOM element for later use', () => {
 | 
			
		||||
    // https://on.cypress.io/as
 | 
			
		||||
@@ -12,31 +12,25 @@ context('Aliasing', () => {
 | 
			
		||||
    // We don't have to traverse to the element
 | 
			
		||||
    // later in our code, we reference it with @
 | 
			
		||||
 | 
			
		||||
    cy.get('.as-table').find('tbody>tr')
 | 
			
		||||
      .first().find('td').first()
 | 
			
		||||
      .find('button').as('firstBtn')
 | 
			
		||||
    cy.get('.as-table').find('tbody>tr').first().find('td').first().find('button').as('firstBtn');
 | 
			
		||||
 | 
			
		||||
    // when we reference the alias, we place an
 | 
			
		||||
    // @ in front of its name
 | 
			
		||||
    cy.get('@firstBtn').click()
 | 
			
		||||
    cy.get('@firstBtn').click();
 | 
			
		||||
 | 
			
		||||
    cy.get('@firstBtn')
 | 
			
		||||
      .should('have.class', 'btn-success')
 | 
			
		||||
      .and('contain', 'Changed')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('@firstBtn').should('have.class', 'btn-success').and('contain', 'Changed');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.as() - alias a route for later use', () => {
 | 
			
		||||
 | 
			
		||||
    // Alias the route to wait for its response
 | 
			
		||||
    cy.server()
 | 
			
		||||
    cy.route('GET', 'comments/*').as('getComment')
 | 
			
		||||
    cy.server();
 | 
			
		||||
    cy.route('GET', 'comments/*').as('getComment');
 | 
			
		||||
 | 
			
		||||
    // we have code that gets a comment when
 | 
			
		||||
    // the button is clicked in scripts.js
 | 
			
		||||
    cy.get('.network-btn').click()
 | 
			
		||||
    cy.get('.network-btn').click();
 | 
			
		||||
 | 
			
		||||
    // https://on.cypress.io/wait
 | 
			
		||||
    cy.wait('@getComment').its('status').should('eq', 200)
 | 
			
		||||
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    cy.wait('@getComment').its('status').should('eq', 200);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,8 @@
 | 
			
		||||
 | 
			
		||||
context('Assertions', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/assertions')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/assertions');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Implicit Assertions', () => {
 | 
			
		||||
    it('.should() - make an assertion about the current subject', () => {
 | 
			
		||||
@@ -23,7 +23,7 @@ context('Assertions', () => {
 | 
			
		||||
        // first need to invoke jQuery method text()
 | 
			
		||||
        // and then match using regular expression
 | 
			
		||||
        .invoke('text')
 | 
			
		||||
        .should('match', /column content/i)
 | 
			
		||||
        .should('match', /column content/i);
 | 
			
		||||
 | 
			
		||||
      // a better way to check element's text content against a regular expression
 | 
			
		||||
      // is to use "cy.contains"
 | 
			
		||||
@@ -32,33 +32,33 @@ context('Assertions', () => {
 | 
			
		||||
        .find('tbody tr:last')
 | 
			
		||||
        // finds first <td> element with text content matching regular expression
 | 
			
		||||
        .contains('td', /column content/i)
 | 
			
		||||
        .should('be.visible')
 | 
			
		||||
        .should('be.visible');
 | 
			
		||||
 | 
			
		||||
      // for more information about asserting element's text
 | 
			
		||||
      // see https://on.cypress.io/using-cypress-faq#How-do-I-get-an-element’s-text-contents
 | 
			
		||||
    })
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('.and() - chain multiple assertions together', () => {
 | 
			
		||||
      // https://on.cypress.io/and
 | 
			
		||||
      cy.get('.assertions-link')
 | 
			
		||||
        .should('have.class', 'active')
 | 
			
		||||
        .and('have.attr', 'href')
 | 
			
		||||
        .and('include', 'cypress.io')
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
        .and('include', 'cypress.io');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Explicit Assertions', () => {
 | 
			
		||||
    // https://on.cypress.io/assertions
 | 
			
		||||
    it('expect - make an assertion about a specified subject', () => {
 | 
			
		||||
      // We can use Chai's BDD style assertions
 | 
			
		||||
      expect(true).to.be.true
 | 
			
		||||
      const o = { foo: 'bar' }
 | 
			
		||||
      expect(true).to.be.true;
 | 
			
		||||
      const o = { foo: 'bar' };
 | 
			
		||||
 | 
			
		||||
      expect(o).to.equal(o)
 | 
			
		||||
      expect(o).to.deep.equal({ foo: 'bar' })
 | 
			
		||||
      expect(o).to.equal(o);
 | 
			
		||||
      expect(o).to.deep.equal({ foo: 'bar' });
 | 
			
		||||
      // matching text using regular expression
 | 
			
		||||
      expect('FooBar').to.match(/bar$/i)
 | 
			
		||||
    })
 | 
			
		||||
      expect('FooBar').to.match(/bar$/i);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('pass your own callback function to should()', () => {
 | 
			
		||||
      // Pass a function to should that can have any number
 | 
			
		||||
@@ -71,14 +71,14 @@ context('Assertions', () => {
 | 
			
		||||
          // https://on.cypress.io/$
 | 
			
		||||
          // return an array of texts from all of the p's
 | 
			
		||||
          // @ts-ignore TS6133 unused variable
 | 
			
		||||
          const texts = $p.map((i, el) => Cypress.$(el).text())
 | 
			
		||||
          const texts = $p.map((i, el) => Cypress.$(el).text());
 | 
			
		||||
 | 
			
		||||
          // jquery map returns jquery object
 | 
			
		||||
          // and .get() convert this to simple array
 | 
			
		||||
          const paragraphs = texts.get()
 | 
			
		||||
          const paragraphs = texts.get();
 | 
			
		||||
 | 
			
		||||
          // array should have length of 3
 | 
			
		||||
          expect(paragraphs, 'has 3 paragraphs').to.have.length(3)
 | 
			
		||||
          expect(paragraphs, 'has 3 paragraphs').to.have.length(3);
 | 
			
		||||
 | 
			
		||||
          // use second argument to expect(...) to provide clear
 | 
			
		||||
          // message with each assertion
 | 
			
		||||
@@ -86,27 +86,27 @@ context('Assertions', () => {
 | 
			
		||||
            'Some text from first p',
 | 
			
		||||
            'More text from second p',
 | 
			
		||||
            'And even more text from third p',
 | 
			
		||||
          ])
 | 
			
		||||
        })
 | 
			
		||||
    })
 | 
			
		||||
          ]);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('finds element by class name regex', () => {
 | 
			
		||||
      cy.get('.docs-header')
 | 
			
		||||
        .find('div')
 | 
			
		||||
        // .should(cb) callback function will be retried
 | 
			
		||||
        .should(($div) => {
 | 
			
		||||
          expect($div).to.have.length(1)
 | 
			
		||||
          expect($div).to.have.length(1);
 | 
			
		||||
 | 
			
		||||
          const className = $div[0].className
 | 
			
		||||
          const className = $div[0].className;
 | 
			
		||||
 | 
			
		||||
          expect(className).to.match(/heading-/)
 | 
			
		||||
          expect(className).to.match(/heading-/);
 | 
			
		||||
        })
 | 
			
		||||
        // .then(cb) callback is not retried,
 | 
			
		||||
        // it either passes or fails
 | 
			
		||||
        .then(($div) => {
 | 
			
		||||
          expect($div, 'text content').to.have.text('Introduction')
 | 
			
		||||
        })
 | 
			
		||||
    })
 | 
			
		||||
          expect($div, 'text content').to.have.text('Introduction');
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('can throw any error', () => {
 | 
			
		||||
      cy.get('.docs-header')
 | 
			
		||||
@@ -114,55 +114,56 @@ context('Assertions', () => {
 | 
			
		||||
        .should(($div) => {
 | 
			
		||||
          if ($div.length !== 1) {
 | 
			
		||||
            // you can throw your own errors
 | 
			
		||||
            throw new Error('Did not find 1 element')
 | 
			
		||||
            throw new Error('Did not find 1 element');
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          const className = $div[0].className
 | 
			
		||||
          const className = $div[0].className;
 | 
			
		||||
 | 
			
		||||
          if (!className.match(/heading-/)) {
 | 
			
		||||
            throw new Error(`Could not find class "heading-" in ${className}`)
 | 
			
		||||
            throw new Error(`Could not find class "heading-" in ${className}`);
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
    })
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('matches unknown text between two elements', () => {
 | 
			
		||||
      /**
 | 
			
		||||
       * Text from the first element.
 | 
			
		||||
       *
 | 
			
		||||
       * @type {string}
 | 
			
		||||
      */
 | 
			
		||||
      let text
 | 
			
		||||
       */
 | 
			
		||||
      let text;
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Normalizes passed text,
 | 
			
		||||
       * useful before comparing text with spaces and different capitalization.
 | 
			
		||||
       * Normalizes passed text, useful before comparing text with spaces and different capitalization.
 | 
			
		||||
       *
 | 
			
		||||
       * @param {string} s Text to normalize
 | 
			
		||||
      */
 | 
			
		||||
      const normalizeText = (s) => s.replace(/\s/g, '').toLowerCase()
 | 
			
		||||
       */
 | 
			
		||||
      const normalizeText = (s) => s.replace(/\s/g, '').toLowerCase();
 | 
			
		||||
 | 
			
		||||
      cy.get('.two-elements')
 | 
			
		||||
        .find('.first')
 | 
			
		||||
        .then(($first) => {
 | 
			
		||||
          // save text from the first element
 | 
			
		||||
          text = normalizeText($first.text())
 | 
			
		||||
        })
 | 
			
		||||
          text = normalizeText($first.text());
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
      cy.get('.two-elements')
 | 
			
		||||
        .find('.second')
 | 
			
		||||
        .should(($div) => {
 | 
			
		||||
          // we can massage text before comparing
 | 
			
		||||
          const secondText = normalizeText($div.text())
 | 
			
		||||
          const secondText = normalizeText($div.text());
 | 
			
		||||
 | 
			
		||||
          expect(secondText, 'second text').to.equal(text)
 | 
			
		||||
        })
 | 
			
		||||
    })
 | 
			
		||||
          expect(secondText, 'second text').to.equal(text);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('assert - assert shape of an object', () => {
 | 
			
		||||
      const person = {
 | 
			
		||||
        name: 'Joe',
 | 
			
		||||
        age: 20,
 | 
			
		||||
      }
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      assert.isObject(person, 'value is object')
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
      assert.isObject(person, 'value is object');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,55 +2,54 @@
 | 
			
		||||
 | 
			
		||||
context('Connectors', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/connectors')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/connectors');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.each() - iterate over an array of elements', () => {
 | 
			
		||||
    // https://on.cypress.io/each
 | 
			
		||||
    cy.get('.connectors-each-ul>li')
 | 
			
		||||
      .each(($el, index, $list) => {
 | 
			
		||||
        console.log($el, index, $list)
 | 
			
		||||
      })
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.connectors-each-ul>li').each(($el, index, $list) => {
 | 
			
		||||
      console.log($el, index, $list);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.its() - get properties on the current subject', () => {
 | 
			
		||||
    // https://on.cypress.io/its
 | 
			
		||||
    cy.get('.connectors-its-ul>li')
 | 
			
		||||
      // calls the 'length' property yielding that value
 | 
			
		||||
      .its('length')
 | 
			
		||||
      .should('be.gt', 2)
 | 
			
		||||
  })
 | 
			
		||||
      .should('be.gt', 2);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.invoke() - invoke a function on the current subject', () => {
 | 
			
		||||
    // our div is hidden in our script.js
 | 
			
		||||
    // $('.connectors-div').hide()
 | 
			
		||||
 | 
			
		||||
    // https://on.cypress.io/invoke
 | 
			
		||||
    cy.get('.connectors-div').should('be.hidden')
 | 
			
		||||
    cy.get('.connectors-div')
 | 
			
		||||
      .should('be.hidden')
 | 
			
		||||
      // call the jquery method 'show' on the 'div.container'
 | 
			
		||||
      .invoke('show')
 | 
			
		||||
      .should('be.visible')
 | 
			
		||||
  })
 | 
			
		||||
      .should('be.visible');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.spread() - spread an array as individual args to callback function', () => {
 | 
			
		||||
    // https://on.cypress.io/spread
 | 
			
		||||
    const arr = ['foo', 'bar', 'baz']
 | 
			
		||||
    const arr = ['foo', 'bar', 'baz'];
 | 
			
		||||
 | 
			
		||||
    cy.wrap(arr).spread((foo, bar, baz) => {
 | 
			
		||||
      expect(foo).to.eq('foo')
 | 
			
		||||
      expect(bar).to.eq('bar')
 | 
			
		||||
      expect(baz).to.eq('baz')
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
      expect(foo).to.eq('foo');
 | 
			
		||||
      expect(bar).to.eq('bar');
 | 
			
		||||
      expect(baz).to.eq('baz');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.then() - invoke a callback function with the current subject', () => {
 | 
			
		||||
    // https://on.cypress.io/then
 | 
			
		||||
    cy.get('.connectors-list > li')
 | 
			
		||||
      .then(($lis) => {
 | 
			
		||||
        expect($lis, '3 items').to.have.length(3)
 | 
			
		||||
        expect($lis.eq(0), 'first item').to.contain('Walk the dog')
 | 
			
		||||
        expect($lis.eq(1), 'second item').to.contain('Feed the cat')
 | 
			
		||||
        expect($lis.eq(2), 'third item').to.contain('Write JavaScript')
 | 
			
		||||
      })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    cy.get('.connectors-list > li').then(($lis) => {
 | 
			
		||||
      expect($lis, '3 items').to.have.length(3);
 | 
			
		||||
      expect($lis.eq(0), 'first item').to.contain('Walk the dog');
 | 
			
		||||
      expect($lis.eq(1), 'second item').to.contain('Feed the cat');
 | 
			
		||||
      expect($lis.eq(2), 'third item').to.contain('Write JavaScript');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,77 +2,78 @@
 | 
			
		||||
 | 
			
		||||
context('Cookies', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    Cypress.Cookies.debug(true)
 | 
			
		||||
    Cypress.Cookies.debug(true);
 | 
			
		||||
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/cookies')
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/cookies');
 | 
			
		||||
 | 
			
		||||
    // clear cookies again after visiting to remove
 | 
			
		||||
    // any 3rd party cookies picked up such as cloudflare
 | 
			
		||||
    cy.clearCookies()
 | 
			
		||||
  })
 | 
			
		||||
    cy.clearCookies();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.getCookie() - get a browser cookie', () => {
 | 
			
		||||
    // https://on.cypress.io/getcookie
 | 
			
		||||
    cy.get('#getCookie .set-a-cookie').click()
 | 
			
		||||
    cy.get('#getCookie .set-a-cookie').click();
 | 
			
		||||
 | 
			
		||||
    // cy.getCookie() yields a cookie object
 | 
			
		||||
    cy.getCookie('token').should('have.property', 'value', '123ABC')
 | 
			
		||||
  })
 | 
			
		||||
    cy.getCookie('token').should('have.property', 'value', '123ABC');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.getCookies() - get browser cookies', () => {
 | 
			
		||||
    // https://on.cypress.io/getcookies
 | 
			
		||||
    cy.getCookies().should('be.empty')
 | 
			
		||||
    cy.getCookies().should('be.empty');
 | 
			
		||||
 | 
			
		||||
    cy.get('#getCookies .set-a-cookie').click()
 | 
			
		||||
    cy.get('#getCookies .set-a-cookie').click();
 | 
			
		||||
 | 
			
		||||
    // cy.getCookies() yields an array of cookies
 | 
			
		||||
    cy.getCookies().should('have.length', 1).should((cookies) => {
 | 
			
		||||
 | 
			
		||||
      // each cookie has these properties
 | 
			
		||||
      expect(cookies[0]).to.have.property('name', 'token')
 | 
			
		||||
      expect(cookies[0]).to.have.property('value', '123ABC')
 | 
			
		||||
      expect(cookies[0]).to.have.property('httpOnly', false)
 | 
			
		||||
      expect(cookies[0]).to.have.property('secure', false)
 | 
			
		||||
      expect(cookies[0]).to.have.property('domain')
 | 
			
		||||
      expect(cookies[0]).to.have.property('path')
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
    cy.getCookies()
 | 
			
		||||
      .should('have.length', 1)
 | 
			
		||||
      .should((cookies) => {
 | 
			
		||||
        // each cookie has these properties
 | 
			
		||||
        expect(cookies[0]).to.have.property('name', 'token');
 | 
			
		||||
        expect(cookies[0]).to.have.property('value', '123ABC');
 | 
			
		||||
        expect(cookies[0]).to.have.property('httpOnly', false);
 | 
			
		||||
        expect(cookies[0]).to.have.property('secure', false);
 | 
			
		||||
        expect(cookies[0]).to.have.property('domain');
 | 
			
		||||
        expect(cookies[0]).to.have.property('path');
 | 
			
		||||
      });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.setCookie() - set a browser cookie', () => {
 | 
			
		||||
    // https://on.cypress.io/setcookie
 | 
			
		||||
    cy.getCookies().should('be.empty')
 | 
			
		||||
    cy.getCookies().should('be.empty');
 | 
			
		||||
 | 
			
		||||
    cy.setCookie('foo', 'bar')
 | 
			
		||||
    cy.setCookie('foo', 'bar');
 | 
			
		||||
 | 
			
		||||
    // cy.getCookie() yields a cookie object
 | 
			
		||||
    cy.getCookie('foo').should('have.property', 'value', 'bar')
 | 
			
		||||
  })
 | 
			
		||||
    cy.getCookie('foo').should('have.property', 'value', 'bar');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.clearCookie() - clear a browser cookie', () => {
 | 
			
		||||
    // https://on.cypress.io/clearcookie
 | 
			
		||||
    cy.getCookie('token').should('be.null')
 | 
			
		||||
    cy.getCookie('token').should('be.null');
 | 
			
		||||
 | 
			
		||||
    cy.get('#clearCookie .set-a-cookie').click()
 | 
			
		||||
    cy.get('#clearCookie .set-a-cookie').click();
 | 
			
		||||
 | 
			
		||||
    cy.getCookie('token').should('have.property', 'value', '123ABC')
 | 
			
		||||
    cy.getCookie('token').should('have.property', 'value', '123ABC');
 | 
			
		||||
 | 
			
		||||
    // cy.clearCookies() yields null
 | 
			
		||||
    cy.clearCookie('token').should('be.null')
 | 
			
		||||
    cy.clearCookie('token').should('be.null');
 | 
			
		||||
 | 
			
		||||
    cy.getCookie('token').should('be.null')
 | 
			
		||||
  })
 | 
			
		||||
    cy.getCookie('token').should('be.null');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.clearCookies() - clear browser cookies', () => {
 | 
			
		||||
    // https://on.cypress.io/clearcookies
 | 
			
		||||
    cy.getCookies().should('be.empty')
 | 
			
		||||
    cy.getCookies().should('be.empty');
 | 
			
		||||
 | 
			
		||||
    cy.get('#clearCookies .set-a-cookie').click()
 | 
			
		||||
    cy.get('#clearCookies .set-a-cookie').click();
 | 
			
		||||
 | 
			
		||||
    cy.getCookies().should('have.length', 1)
 | 
			
		||||
    cy.getCookies().should('have.length', 1);
 | 
			
		||||
 | 
			
		||||
    // cy.clearCookies() yields null
 | 
			
		||||
    cy.clearCookies()
 | 
			
		||||
    cy.clearCookies();
 | 
			
		||||
 | 
			
		||||
    cy.getCookies().should('be.empty')
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    cy.getCookies().should('be.empty');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,81 +2,85 @@
 | 
			
		||||
 | 
			
		||||
context('Cypress.Commands', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/cypress-api')
 | 
			
		||||
  })
 | 
			
		||||
    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) => {
 | 
			
		||||
      // the previous subject is automatically received
 | 
			
		||||
      // and the commands arguments are shifted
 | 
			
		||||
    Cypress.Commands.add(
 | 
			
		||||
      'console',
 | 
			
		||||
      {
 | 
			
		||||
        prevSubject: true,
 | 
			
		||||
      },
 | 
			
		||||
      (subject, method) => {
 | 
			
		||||
        // the previous subject is automatically received
 | 
			
		||||
        // and the commands arguments are shifted
 | 
			
		||||
 | 
			
		||||
      // allow us to change the console method used
 | 
			
		||||
      method = method || 'log'
 | 
			
		||||
        // allow us to change the console method used
 | 
			
		||||
        method = method || 'log';
 | 
			
		||||
 | 
			
		||||
      // log the subject to the console
 | 
			
		||||
      // @ts-ignore TS7017
 | 
			
		||||
      console[method]('The subject is', subject)
 | 
			
		||||
        // log the subject to the console
 | 
			
		||||
        // @ts-ignore TS7017
 | 
			
		||||
        console[method]('The subject is', subject);
 | 
			
		||||
 | 
			
		||||
      // whatever we return becomes the new subject
 | 
			
		||||
      // we don't want to change the subject so
 | 
			
		||||
      // we return whatever was passed in
 | 
			
		||||
      return subject
 | 
			
		||||
    })
 | 
			
		||||
        // whatever we return becomes the new subject
 | 
			
		||||
        // we don't want to change the subject so
 | 
			
		||||
        // we return whatever was passed in
 | 
			
		||||
        return subject;
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // @ts-ignore TS2339
 | 
			
		||||
    cy.get('button').console('info').then(($button) => {
 | 
			
		||||
      // subject is still $button
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
    cy.get('button')
 | 
			
		||||
      .console('info')
 | 
			
		||||
      .then(($button) => {
 | 
			
		||||
        // subject is still $button
 | 
			
		||||
      });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
context('Cypress.Cookies', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/cypress-api')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/cypress-api');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // https://on.cypress.io/cookies
 | 
			
		||||
  it('.debug() - enable or disable debugging', () => {
 | 
			
		||||
    Cypress.Cookies.debug(true)
 | 
			
		||||
    Cypress.Cookies.debug(true);
 | 
			
		||||
 | 
			
		||||
    // Cypress will now log in the console when
 | 
			
		||||
    // cookies are set or cleared
 | 
			
		||||
    cy.setCookie('fakeCookie', '123ABC')
 | 
			
		||||
    cy.clearCookie('fakeCookie')
 | 
			
		||||
    cy.setCookie('fakeCookie', '123ABC')
 | 
			
		||||
    cy.clearCookie('fakeCookie')
 | 
			
		||||
    cy.setCookie('fakeCookie', '123ABC')
 | 
			
		||||
  })
 | 
			
		||||
    cy.setCookie('fakeCookie', '123ABC');
 | 
			
		||||
    cy.clearCookie('fakeCookie');
 | 
			
		||||
    cy.setCookie('fakeCookie', '123ABC');
 | 
			
		||||
    cy.clearCookie('fakeCookie');
 | 
			
		||||
    cy.setCookie('fakeCookie', '123ABC');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.preserveOnce() - preserve cookies by key', () => {
 | 
			
		||||
    // normally cookies are reset after each test
 | 
			
		||||
    cy.getCookie('fakeCookie').should('not.be.ok')
 | 
			
		||||
    cy.getCookie('fakeCookie').should('not.be.ok');
 | 
			
		||||
 | 
			
		||||
    // preserving a cookie will not clear it when
 | 
			
		||||
    // the next test starts
 | 
			
		||||
    cy.setCookie('lastCookie', '789XYZ')
 | 
			
		||||
    Cypress.Cookies.preserveOnce('lastCookie')
 | 
			
		||||
  })
 | 
			
		||||
    cy.setCookie('lastCookie', '789XYZ');
 | 
			
		||||
    Cypress.Cookies.preserveOnce('lastCookie');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.defaults() - set defaults for all cookies', () => {
 | 
			
		||||
    // now any cookie with the name 'session_id' will
 | 
			
		||||
    // not be cleared before each new test runs
 | 
			
		||||
    Cypress.Cookies.defaults({
 | 
			
		||||
      whitelist: 'session_id',
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
context('Cypress.Server', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/cypress-api')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/cypress-api');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Permanently override server options for
 | 
			
		||||
  // all instances of cy.server()
 | 
			
		||||
@@ -86,71 +90,71 @@ context('Cypress.Server', () => {
 | 
			
		||||
    Cypress.Server.defaults({
 | 
			
		||||
      delay: 0,
 | 
			
		||||
      force404: false,
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
context('Cypress.arch', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/cypress-api')
 | 
			
		||||
  })
 | 
			
		||||
    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
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    expect(Cypress.arch).to.exist;
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
context('Cypress.config()', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/cypress-api')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/cypress-api');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('Get and set configuration options', () => {
 | 
			
		||||
    // https://on.cypress.io/config
 | 
			
		||||
    let myConfig = Cypress.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(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)
 | 
			
		||||
    expect(Cypress.config('pageLoadTimeout')).to.eq(60000);
 | 
			
		||||
 | 
			
		||||
    // this will change the config for the rest of your tests!
 | 
			
		||||
    Cypress.config('pageLoadTimeout', 20000)
 | 
			
		||||
    Cypress.config('pageLoadTimeout', 20000);
 | 
			
		||||
 | 
			
		||||
    expect(Cypress.config('pageLoadTimeout')).to.eq(20000)
 | 
			
		||||
    expect(Cypress.config('pageLoadTimeout')).to.eq(20000);
 | 
			
		||||
 | 
			
		||||
    Cypress.config('pageLoadTimeout', 60000)
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    Cypress.config('pageLoadTimeout', 60000);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
context('Cypress.dom', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/cypress-api')
 | 
			
		||||
  })
 | 
			
		||||
    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)
 | 
			
		||||
    let hiddenP = Cypress.$('.dom-p p.hidden').get(0);
 | 
			
		||||
    let visibleP = Cypress.$('.dom-p p.visible').get(0);
 | 
			
		||||
 | 
			
		||||
    // our first paragraph has css class 'hidden'
 | 
			
		||||
    expect(Cypress.dom.isHidden(hiddenP)).to.be.true
 | 
			
		||||
    expect(Cypress.dom.isHidden(visibleP)).to.be.false
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    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')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/cypress-api');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // We can set environment variables for highly dynamic values
 | 
			
		||||
 | 
			
		||||
@@ -161,62 +165,61 @@ context('Cypress.env()', () => {
 | 
			
		||||
    Cypress.env({
 | 
			
		||||
      host: 'veronica.dev.local',
 | 
			
		||||
      api_server: 'http://localhost:8888/v1/',
 | 
			
		||||
    })
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // get environment variable
 | 
			
		||||
    expect(Cypress.env('host')).to.eq('veronica.dev.local')
 | 
			
		||||
    expect(Cypress.env('host')).to.eq('veronica.dev.local');
 | 
			
		||||
 | 
			
		||||
    // set environment variable
 | 
			
		||||
    Cypress.env('api_server', 'http://localhost:8888/v2/')
 | 
			
		||||
    expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/')
 | 
			
		||||
    Cypress.env('api_server', 'http://localhost:8888/v2/');
 | 
			
		||||
    expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/');
 | 
			
		||||
 | 
			
		||||
    // get all environment variable
 | 
			
		||||
    expect(Cypress.env()).to.have.property('host', 'veronica.dev.local')
 | 
			
		||||
    expect(Cypress.env()).to.have.property('api_server', 'http://localhost:8888/v2/')
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    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')
 | 
			
		||||
  })
 | 
			
		||||
    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')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/cypress-api');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('Get underlying OS name', () => {
 | 
			
		||||
    // https://on.cypress.io/platform
 | 
			
		||||
    expect(Cypress.platform).to.be.exist
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    expect(Cypress.platform).to.be.exist;
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
context('Cypress.version', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/cypress-api')
 | 
			
		||||
  })
 | 
			
		||||
    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
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    expect(Cypress.version).to.be.exist;
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
context('Cypress.spec', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/cypress-api')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/cypress-api');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('Get current spec information', () => {
 | 
			
		||||
    // https://on.cypress.io/spec
 | 
			
		||||
    // wrap the object so we can inspect it easily by clicking in the command log
 | 
			
		||||
    cy.wrap(Cypress.spec).should('have.keys', ['name', 'relative', 'absolute'])
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    cy.wrap(Cypress.spec).should('have.keys', ['name', 'relative', 'absolute']);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -3,18 +3,18 @@
 | 
			
		||||
/// JSON fixture file can be loaded directly using
 | 
			
		||||
// the built-in JavaScript bundler
 | 
			
		||||
// @ts-ignore
 | 
			
		||||
const requiredExample = require('../../fixtures/example')
 | 
			
		||||
const requiredExample = require('../../fixtures/example');
 | 
			
		||||
 | 
			
		||||
context('Files', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/files')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/files');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    // load example.json fixture file and store
 | 
			
		||||
    // in the test context object
 | 
			
		||||
    cy.fixture('example.json').as('example')
 | 
			
		||||
  })
 | 
			
		||||
    cy.fixture('example.json').as('example');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.fixture() - load a fixture', () => {
 | 
			
		||||
    // https://on.cypress.io/fixture
 | 
			
		||||
@@ -22,57 +22,58 @@ context('Files', () => {
 | 
			
		||||
    // Instead of writing a response inline you can
 | 
			
		||||
    // use a fixture file's content.
 | 
			
		||||
 | 
			
		||||
    cy.server()
 | 
			
		||||
    cy.fixture('example.json').as('comment')
 | 
			
		||||
    cy.server();
 | 
			
		||||
    cy.fixture('example.json').as('comment');
 | 
			
		||||
    // when application makes an Ajax request matching "GET comments/*"
 | 
			
		||||
    // Cypress will intercept it and reply with object
 | 
			
		||||
    // from the "comment" alias
 | 
			
		||||
    cy.route('GET', 'comments/*', '@comment').as('getComment')
 | 
			
		||||
    cy.route('GET', 'comments/*', '@comment').as('getComment');
 | 
			
		||||
 | 
			
		||||
    // we have code that gets a comment when
 | 
			
		||||
    // the button is clicked in scripts.js
 | 
			
		||||
    cy.get('.fixture-btn').click()
 | 
			
		||||
    cy.get('.fixture-btn').click();
 | 
			
		||||
 | 
			
		||||
    cy.wait('@getComment').its('responseBody')
 | 
			
		||||
    cy.wait('@getComment')
 | 
			
		||||
      .its('responseBody')
 | 
			
		||||
      .should('have.property', 'name')
 | 
			
		||||
      .and('include', 'Using fixtures to represent data')
 | 
			
		||||
      .and('include', 'Using fixtures to represent data');
 | 
			
		||||
 | 
			
		||||
    // you can also just write the fixture in the route
 | 
			
		||||
    cy.route('GET', 'comments/*', 'fixture:example.json').as('getComment')
 | 
			
		||||
    cy.route('GET', 'comments/*', 'fixture:example.json').as('getComment');
 | 
			
		||||
 | 
			
		||||
    // we have code that gets a comment when
 | 
			
		||||
    // the button is clicked in scripts.js
 | 
			
		||||
    cy.get('.fixture-btn').click()
 | 
			
		||||
    cy.get('.fixture-btn').click();
 | 
			
		||||
 | 
			
		||||
    cy.wait('@getComment').its('responseBody')
 | 
			
		||||
    cy.wait('@getComment')
 | 
			
		||||
      .its('responseBody')
 | 
			
		||||
      .should('have.property', 'name')
 | 
			
		||||
      .and('include', 'Using fixtures to represent data')
 | 
			
		||||
      .and('include', 'Using fixtures to represent data');
 | 
			
		||||
 | 
			
		||||
    // or write fx to represent fixture
 | 
			
		||||
    // by default it assumes it's .json
 | 
			
		||||
    cy.route('GET', 'comments/*', 'fx:example').as('getComment')
 | 
			
		||||
    cy.route('GET', 'comments/*', 'fx:example').as('getComment');
 | 
			
		||||
 | 
			
		||||
    // we have code that gets a comment when
 | 
			
		||||
    // the button is clicked in scripts.js
 | 
			
		||||
    cy.get('.fixture-btn').click()
 | 
			
		||||
    cy.get('.fixture-btn').click();
 | 
			
		||||
 | 
			
		||||
    cy.wait('@getComment').its('responseBody')
 | 
			
		||||
    cy.wait('@getComment')
 | 
			
		||||
      .its('responseBody')
 | 
			
		||||
      .should('have.property', 'name')
 | 
			
		||||
      .and('include', 'Using fixtures to represent data')
 | 
			
		||||
  })
 | 
			
		||||
      .and('include', 'Using fixtures to represent data');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.fixture() or require - load a fixture', function () {
 | 
			
		||||
    // we are inside the "function () { ... }"
 | 
			
		||||
    // callback and can use test context object "this"
 | 
			
		||||
    // "this.example" was loaded in "beforeEach" function callback
 | 
			
		||||
    expect(this.example, 'fixture in the test context')
 | 
			
		||||
      .to.deep.equal(requiredExample)
 | 
			
		||||
    expect(this.example, 'fixture in the test context').to.deep.equal(requiredExample);
 | 
			
		||||
 | 
			
		||||
    // or use "cy.wrap" and "should('deep.equal', ...)" assertion
 | 
			
		||||
    // @ts-ignore
 | 
			
		||||
    cy.wrap(this.example, 'fixture vs require')
 | 
			
		||||
      .should('deep.equal', requiredExample)
 | 
			
		||||
  })
 | 
			
		||||
    cy.wrap(this.example, 'fixture vs require').should('deep.equal', requiredExample);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.readFile() - read a files contents', () => {
 | 
			
		||||
    // https://on.cypress.io/readfile
 | 
			
		||||
@@ -80,9 +81,9 @@ context('Files', () => {
 | 
			
		||||
    // You can read a file and yield its contents
 | 
			
		||||
    // The filePath is relative to your project's root.
 | 
			
		||||
    cy.readFile('cypress.json').then((json) => {
 | 
			
		||||
      expect(json).to.be.an('object')
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
      expect(json).to.be.an('object');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.writeFile() - write to a file', () => {
 | 
			
		||||
    // https://on.cypress.io/writefile
 | 
			
		||||
@@ -91,13 +92,12 @@ context('Files', () => {
 | 
			
		||||
 | 
			
		||||
    // Use a response from a request to automatically
 | 
			
		||||
    // generate a fixture file for use later
 | 
			
		||||
    cy.request('https://jsonplaceholder.cypress.io/users')
 | 
			
		||||
      .then((response) => {
 | 
			
		||||
        cy.writeFile('cypress/fixtures/users.json', response.body)
 | 
			
		||||
      })
 | 
			
		||||
    cy.request('https://jsonplaceholder.cypress.io/users').then((response) => {
 | 
			
		||||
      cy.writeFile('cypress/fixtures/users.json', response.body);
 | 
			
		||||
    });
 | 
			
		||||
    cy.fixture('users').should((users) => {
 | 
			
		||||
      expect(users[0].name).to.exist
 | 
			
		||||
    })
 | 
			
		||||
      expect(users[0].name).to.exist;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // JavaScript arrays and objects are stringified
 | 
			
		||||
    // and formatted into text.
 | 
			
		||||
@@ -105,10 +105,10 @@ context('Files', () => {
 | 
			
		||||
      id: 8739,
 | 
			
		||||
      name: 'Jane',
 | 
			
		||||
      email: 'jane@example.com',
 | 
			
		||||
    })
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    cy.fixture('profile').should((profile) => {
 | 
			
		||||
      expect(profile.name).to.eq('Jane')
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
      expect(profile.name).to.eq('Jane');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,51 +2,57 @@
 | 
			
		||||
 | 
			
		||||
context('Local Storage', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/local-storage')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/local-storage');
 | 
			
		||||
  });
 | 
			
		||||
  // Although local storage is automatically cleared
 | 
			
		||||
  // in between tests to maintain a clean state
 | 
			
		||||
  // sometimes we need to clear the local storage manually
 | 
			
		||||
 | 
			
		||||
  it('cy.clearLocalStorage() - clear all data in local storage', () => {
 | 
			
		||||
    // https://on.cypress.io/clearlocalstorage
 | 
			
		||||
    cy.get('.ls-btn').click().should(() => {
 | 
			
		||||
      expect(localStorage.getItem('prop1')).to.eq('red')
 | 
			
		||||
      expect(localStorage.getItem('prop2')).to.eq('blue')
 | 
			
		||||
      expect(localStorage.getItem('prop3')).to.eq('magenta')
 | 
			
		||||
    })
 | 
			
		||||
    cy.get('.ls-btn')
 | 
			
		||||
      .click()
 | 
			
		||||
      .should(() => {
 | 
			
		||||
        expect(localStorage.getItem('prop1')).to.eq('red');
 | 
			
		||||
        expect(localStorage.getItem('prop2')).to.eq('blue');
 | 
			
		||||
        expect(localStorage.getItem('prop3')).to.eq('magenta');
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    // clearLocalStorage() yields the localStorage object
 | 
			
		||||
    cy.clearLocalStorage().should((ls) => {
 | 
			
		||||
      expect(ls.getItem('prop1')).to.be.null
 | 
			
		||||
      expect(ls.getItem('prop2')).to.be.null
 | 
			
		||||
      expect(ls.getItem('prop3')).to.be.null
 | 
			
		||||
    })
 | 
			
		||||
      expect(ls.getItem('prop1')).to.be.null;
 | 
			
		||||
      expect(ls.getItem('prop2')).to.be.null;
 | 
			
		||||
      expect(ls.getItem('prop3')).to.be.null;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Clear key matching string in Local Storage
 | 
			
		||||
    cy.get('.ls-btn').click().should(() => {
 | 
			
		||||
      expect(localStorage.getItem('prop1')).to.eq('red')
 | 
			
		||||
      expect(localStorage.getItem('prop2')).to.eq('blue')
 | 
			
		||||
      expect(localStorage.getItem('prop3')).to.eq('magenta')
 | 
			
		||||
    })
 | 
			
		||||
    cy.get('.ls-btn')
 | 
			
		||||
      .click()
 | 
			
		||||
      .should(() => {
 | 
			
		||||
        expect(localStorage.getItem('prop1')).to.eq('red');
 | 
			
		||||
        expect(localStorage.getItem('prop2')).to.eq('blue');
 | 
			
		||||
        expect(localStorage.getItem('prop3')).to.eq('magenta');
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    cy.clearLocalStorage('prop1').should((ls) => {
 | 
			
		||||
      expect(ls.getItem('prop1')).to.be.null
 | 
			
		||||
      expect(ls.getItem('prop2')).to.eq('blue')
 | 
			
		||||
      expect(ls.getItem('prop3')).to.eq('magenta')
 | 
			
		||||
    })
 | 
			
		||||
      expect(ls.getItem('prop1')).to.be.null;
 | 
			
		||||
      expect(ls.getItem('prop2')).to.eq('blue');
 | 
			
		||||
      expect(ls.getItem('prop3')).to.eq('magenta');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Clear keys matching regex in Local Storage
 | 
			
		||||
    cy.get('.ls-btn').click().should(() => {
 | 
			
		||||
      expect(localStorage.getItem('prop1')).to.eq('red')
 | 
			
		||||
      expect(localStorage.getItem('prop2')).to.eq('blue')
 | 
			
		||||
      expect(localStorage.getItem('prop3')).to.eq('magenta')
 | 
			
		||||
    })
 | 
			
		||||
    cy.get('.ls-btn')
 | 
			
		||||
      .click()
 | 
			
		||||
      .should(() => {
 | 
			
		||||
        expect(localStorage.getItem('prop1')).to.eq('red');
 | 
			
		||||
        expect(localStorage.getItem('prop2')).to.eq('blue');
 | 
			
		||||
        expect(localStorage.getItem('prop3')).to.eq('magenta');
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    cy.clearLocalStorage(/prop1|2/).should((ls) => {
 | 
			
		||||
      expect(ls.getItem('prop1')).to.be.null
 | 
			
		||||
      expect(ls.getItem('prop2')).to.be.null
 | 
			
		||||
      expect(ls.getItem('prop3')).to.eq('magenta')
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
      expect(ls.getItem('prop1')).to.be.null;
 | 
			
		||||
      expect(ls.getItem('prop2')).to.be.null;
 | 
			
		||||
      expect(ls.getItem('prop3')).to.eq('magenta');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,31 +2,31 @@
 | 
			
		||||
 | 
			
		||||
context('Location', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/location')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/location');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.hash() - get the current URL hash', () => {
 | 
			
		||||
    // https://on.cypress.io/hash
 | 
			
		||||
    cy.hash().should('be.empty')
 | 
			
		||||
  })
 | 
			
		||||
    cy.hash().should('be.empty');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.location() - get window.location', () => {
 | 
			
		||||
    // https://on.cypress.io/location
 | 
			
		||||
    cy.location().should((location) => {
 | 
			
		||||
      expect(location.hash).to.be.empty
 | 
			
		||||
      expect(location.href).to.eq('https://example.cypress.io/commands/location')
 | 
			
		||||
      expect(location.host).to.eq('example.cypress.io')
 | 
			
		||||
      expect(location.hostname).to.eq('example.cypress.io')
 | 
			
		||||
      expect(location.origin).to.eq('https://example.cypress.io')
 | 
			
		||||
      expect(location.pathname).to.eq('/commands/location')
 | 
			
		||||
      expect(location.port).to.eq('')
 | 
			
		||||
      expect(location.protocol).to.eq('https:')
 | 
			
		||||
      expect(location.search).to.be.empty
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
      expect(location.hash).to.be.empty;
 | 
			
		||||
      expect(location.href).to.eq('https://example.cypress.io/commands/location');
 | 
			
		||||
      expect(location.host).to.eq('example.cypress.io');
 | 
			
		||||
      expect(location.hostname).to.eq('example.cypress.io');
 | 
			
		||||
      expect(location.origin).to.eq('https://example.cypress.io');
 | 
			
		||||
      expect(location.pathname).to.eq('/commands/location');
 | 
			
		||||
      expect(location.port).to.eq('');
 | 
			
		||||
      expect(location.protocol).to.eq('https:');
 | 
			
		||||
      expect(location.search).to.be.empty;
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.url() - get the current URL', () => {
 | 
			
		||||
    // https://on.cypress.io/url
 | 
			
		||||
    cy.url().should('eq', 'https://example.cypress.io/commands/location')
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    cy.url().should('eq', 'https://example.cypress.io/commands/location');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,8 @@
 | 
			
		||||
 | 
			
		||||
context('Misc', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/misc')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/misc');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.end() - end the command chain', () => {
 | 
			
		||||
    // https://on.cypress.io/end
 | 
			
		||||
@@ -12,12 +12,12 @@ context('Misc', () => {
 | 
			
		||||
    // and force Cypress to re-query from the root element
 | 
			
		||||
    cy.get('.misc-table').within(() => {
 | 
			
		||||
      // ends the current chain and yields null
 | 
			
		||||
      cy.contains('Cheryl').click().end()
 | 
			
		||||
      cy.contains('Cheryl').click().end();
 | 
			
		||||
 | 
			
		||||
      // queries the entire table again
 | 
			
		||||
      cy.contains('Charles').click()
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
      cy.contains('Charles').click();
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.exec() - execute a system command', () => {
 | 
			
		||||
    // https://on.cypress.io/exec
 | 
			
		||||
@@ -25,40 +25,36 @@ context('Misc', () => {
 | 
			
		||||
    // execute a system command.
 | 
			
		||||
    // so you can take actions necessary for
 | 
			
		||||
    // your test outside the scope of Cypress.
 | 
			
		||||
    cy.exec('echo Jane Lane')
 | 
			
		||||
      .its('stdout').should('contain', 'Jane Lane')
 | 
			
		||||
    cy.exec('echo Jane Lane').its('stdout').should('contain', 'Jane Lane');
 | 
			
		||||
 | 
			
		||||
    // we can use Cypress.platform string to
 | 
			
		||||
    // select appropriate command
 | 
			
		||||
    // https://on.cypress/io/platform
 | 
			
		||||
    cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`)
 | 
			
		||||
    cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`);
 | 
			
		||||
 | 
			
		||||
    if (Cypress.platform === 'win32') {
 | 
			
		||||
      cy.exec('print cypress.json')
 | 
			
		||||
        .its('stderr').should('be.empty')
 | 
			
		||||
      cy.exec('print cypress.json').its('stderr').should('be.empty');
 | 
			
		||||
    } else {
 | 
			
		||||
      cy.exec('cat cypress.json')
 | 
			
		||||
        .its('stderr').should('be.empty')
 | 
			
		||||
      cy.exec('cat cypress.json').its('stderr').should('be.empty');
 | 
			
		||||
 | 
			
		||||
      cy.exec('pwd')
 | 
			
		||||
        .its('code').should('eq', 0)
 | 
			
		||||
      cy.exec('pwd').its('code').should('eq', 0);
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.focused() - get the DOM element that has focus', () => {
 | 
			
		||||
    // https://on.cypress.io/focused
 | 
			
		||||
    cy.get('.misc-form').find('#name').click()
 | 
			
		||||
    cy.focused().should('have.id', 'name')
 | 
			
		||||
    cy.get('.misc-form').find('#name').click();
 | 
			
		||||
    cy.focused().should('have.id', 'name');
 | 
			
		||||
 | 
			
		||||
    cy.get('.misc-form').find('#description').click()
 | 
			
		||||
    cy.focused().should('have.id', 'description')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.misc-form').find('#description').click();
 | 
			
		||||
    cy.focused().should('have.id', 'description');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  context('Cypress.Screenshot', function () {
 | 
			
		||||
    it('cy.screenshot() - take a screenshot', () => {
 | 
			
		||||
      // https://on.cypress.io/screenshot
 | 
			
		||||
      cy.screenshot('my-image')
 | 
			
		||||
    })
 | 
			
		||||
      cy.screenshot('my-image');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('Cypress.Screenshot.defaults() - change default config of screenshots', function () {
 | 
			
		||||
      Cypress.Screenshot.defaults({
 | 
			
		||||
@@ -68,16 +64,14 @@ context('Misc', () => {
 | 
			
		||||
        scale: false,
 | 
			
		||||
        disableTimersAndAnimations: true,
 | 
			
		||||
        screenshotOnRunFailure: true,
 | 
			
		||||
        beforeScreenshot () { },
 | 
			
		||||
        afterScreenshot () { },
 | 
			
		||||
      })
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
        beforeScreenshot() {},
 | 
			
		||||
        afterScreenshot() {},
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.wrap() - wrap an object', () => {
 | 
			
		||||
    // https://on.cypress.io/wrap
 | 
			
		||||
    cy.wrap({ foo: 'bar' })
 | 
			
		||||
      .should('have.property', 'foo')
 | 
			
		||||
      .and('include', 'bar')
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    cy.wrap({ foo: 'bar' }).should('have.property', 'foo').and('include', 'bar');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,38 +2,38 @@
 | 
			
		||||
 | 
			
		||||
context('Navigation', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io')
 | 
			
		||||
    cy.get('.navbar-nav').contains('Commands').click()
 | 
			
		||||
    cy.get('.dropdown-menu').contains('Navigation').click()
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io');
 | 
			
		||||
    cy.get('.navbar-nav').contains('Commands').click();
 | 
			
		||||
    cy.get('.dropdown-menu').contains('Navigation').click();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.go() - go back or forward in the browser\'s history', () => {
 | 
			
		||||
  it("cy.go() - go back or forward in the browser's history", () => {
 | 
			
		||||
    // https://on.cypress.io/go
 | 
			
		||||
 | 
			
		||||
    cy.location('pathname').should('include', 'navigation')
 | 
			
		||||
    cy.location('pathname').should('include', 'navigation');
 | 
			
		||||
 | 
			
		||||
    cy.go('back')
 | 
			
		||||
    cy.location('pathname').should('not.include', 'navigation')
 | 
			
		||||
    cy.go('back');
 | 
			
		||||
    cy.location('pathname').should('not.include', 'navigation');
 | 
			
		||||
 | 
			
		||||
    cy.go('forward')
 | 
			
		||||
    cy.location('pathname').should('include', 'navigation')
 | 
			
		||||
    cy.go('forward');
 | 
			
		||||
    cy.location('pathname').should('include', 'navigation');
 | 
			
		||||
 | 
			
		||||
    // clicking back
 | 
			
		||||
    cy.go(-1)
 | 
			
		||||
    cy.location('pathname').should('not.include', 'navigation')
 | 
			
		||||
    cy.go(-1);
 | 
			
		||||
    cy.location('pathname').should('not.include', 'navigation');
 | 
			
		||||
 | 
			
		||||
    // clicking forward
 | 
			
		||||
    cy.go(1)
 | 
			
		||||
    cy.location('pathname').should('include', 'navigation')
 | 
			
		||||
  })
 | 
			
		||||
    cy.go(1);
 | 
			
		||||
    cy.location('pathname').should('include', 'navigation');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.reload() - reload the page', () => {
 | 
			
		||||
    // https://on.cypress.io/reload
 | 
			
		||||
    cy.reload()
 | 
			
		||||
    cy.reload();
 | 
			
		||||
 | 
			
		||||
    // reload the page without using the cache
 | 
			
		||||
    cy.reload(true)
 | 
			
		||||
  })
 | 
			
		||||
    cy.reload(true);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.visit() - visit a remote url', () => {
 | 
			
		||||
    // https://on.cypress.io/visit
 | 
			
		||||
@@ -43,14 +43,14 @@ context('Navigation', () => {
 | 
			
		||||
    // Pass options to the visit
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/navigation', {
 | 
			
		||||
      timeout: 50000, // increase total time for the visit to resolve
 | 
			
		||||
      onBeforeLoad (contentWindow) {
 | 
			
		||||
      onBeforeLoad(contentWindow) {
 | 
			
		||||
        // contentWindow is the remote page's window object
 | 
			
		||||
        expect(typeof contentWindow === 'object').to.be.true
 | 
			
		||||
        expect(typeof contentWindow === 'object').to.be.true;
 | 
			
		||||
      },
 | 
			
		||||
      onLoad (contentWindow) {
 | 
			
		||||
      onLoad(contentWindow) {
 | 
			
		||||
        // contentWindow is the remote page's window object
 | 
			
		||||
        expect(typeof contentWindow === 'object').to.be.true
 | 
			
		||||
        expect(typeof contentWindow === 'object').to.be.true;
 | 
			
		||||
      },
 | 
			
		||||
    })
 | 
			
		||||
    })
 | 
			
		||||
})
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,8 @@
 | 
			
		||||
 | 
			
		||||
context('Network Requests', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/network-requests')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/network-requests');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Manage AJAX / XHR requests in your app
 | 
			
		||||
 | 
			
		||||
@@ -13,59 +13,56 @@ context('Network Requests', () => {
 | 
			
		||||
    cy.server().should((server) => {
 | 
			
		||||
      // the default options on server
 | 
			
		||||
      // you can override any of these options
 | 
			
		||||
      expect(server.delay).to.eq(0)
 | 
			
		||||
      expect(server.method).to.eq('GET')
 | 
			
		||||
      expect(server.status).to.eq(200)
 | 
			
		||||
      expect(server.headers).to.be.null
 | 
			
		||||
      expect(server.response).to.be.null
 | 
			
		||||
      expect(server.onRequest).to.be.undefined
 | 
			
		||||
      expect(server.onResponse).to.be.undefined
 | 
			
		||||
      expect(server.onAbort).to.be.undefined
 | 
			
		||||
      expect(server.delay).to.eq(0);
 | 
			
		||||
      expect(server.method).to.eq('GET');
 | 
			
		||||
      expect(server.status).to.eq(200);
 | 
			
		||||
      expect(server.headers).to.be.null;
 | 
			
		||||
      expect(server.response).to.be.null;
 | 
			
		||||
      expect(server.onRequest).to.be.undefined;
 | 
			
		||||
      expect(server.onResponse).to.be.undefined;
 | 
			
		||||
      expect(server.onAbort).to.be.undefined;
 | 
			
		||||
 | 
			
		||||
      // These options control the server behavior
 | 
			
		||||
      // affecting all requests
 | 
			
		||||
 | 
			
		||||
      // pass false to disable existing route stubs
 | 
			
		||||
      expect(server.enable).to.be.true
 | 
			
		||||
      expect(server.enable).to.be.true;
 | 
			
		||||
      // forces requests that don't match your routes to 404
 | 
			
		||||
      expect(server.force404).to.be.false
 | 
			
		||||
      expect(server.force404).to.be.false;
 | 
			
		||||
      // whitelists requests from ever being logged or stubbed
 | 
			
		||||
      expect(server.whitelist).to.be.a('function')
 | 
			
		||||
    })
 | 
			
		||||
      expect(server.whitelist).to.be.a('function');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    cy.server({
 | 
			
		||||
      method: 'POST',
 | 
			
		||||
      delay: 1000,
 | 
			
		||||
      status: 422,
 | 
			
		||||
      response: {},
 | 
			
		||||
    })
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // any route commands will now inherit the above options
 | 
			
		||||
    // from the server. anything we pass specifically
 | 
			
		||||
    // to route will override the defaults though.
 | 
			
		||||
  })
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.request() - make an XHR request', () => {
 | 
			
		||||
    // https://on.cypress.io/request
 | 
			
		||||
    cy.request('https://jsonplaceholder.cypress.io/comments')
 | 
			
		||||
      .should((response) => {
 | 
			
		||||
        expect(response.status).to.eq(200)
 | 
			
		||||
        expect(response.body).to.have.length(500)
 | 
			
		||||
        expect(response).to.have.property('headers')
 | 
			
		||||
        expect(response).to.have.property('duration')
 | 
			
		||||
      })
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
    cy.request('https://jsonplaceholder.cypress.io/comments').should((response) => {
 | 
			
		||||
      expect(response.status).to.eq(200);
 | 
			
		||||
      expect(response.body).to.have.length(500);
 | 
			
		||||
      expect(response).to.have.property('headers');
 | 
			
		||||
      expect(response).to.have.property('duration');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.request() - verify response using BDD syntax', () => {
 | 
			
		||||
    cy.request('https://jsonplaceholder.cypress.io/comments')
 | 
			
		||||
    .then((response) => {
 | 
			
		||||
    cy.request('https://jsonplaceholder.cypress.io/comments').then((response) => {
 | 
			
		||||
      // https://on.cypress.io/assertions
 | 
			
		||||
      expect(response).property('status').to.equal(200)
 | 
			
		||||
      expect(response).property('body').to.have.length(500)
 | 
			
		||||
      expect(response).to.include.keys('headers', 'duration')
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
      expect(response).property('status').to.equal(200);
 | 
			
		||||
      expect(response).property('body').to.have.length(500);
 | 
			
		||||
      expect(response).to.include.keys('headers', 'duration');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.request() with query parameters', () => {
 | 
			
		||||
    // will execute request
 | 
			
		||||
@@ -77,42 +74,42 @@ context('Network Requests', () => {
 | 
			
		||||
        id: 3,
 | 
			
		||||
      },
 | 
			
		||||
    })
 | 
			
		||||
    .its('body')
 | 
			
		||||
    .should('be.an', 'array')
 | 
			
		||||
    .and('have.length', 1)
 | 
			
		||||
    .its('0') // yields first element of the array
 | 
			
		||||
    .should('contain', {
 | 
			
		||||
      postId: 1,
 | 
			
		||||
      id: 3,
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
      .its('body')
 | 
			
		||||
      .should('be.an', 'array')
 | 
			
		||||
      .and('have.length', 1)
 | 
			
		||||
      .its('0') // yields first element of the array
 | 
			
		||||
      .should('contain', {
 | 
			
		||||
        postId: 1,
 | 
			
		||||
        id: 3,
 | 
			
		||||
      });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.request() - pass result to the second request', () => {
 | 
			
		||||
    // first, let's find out the userId of the first user we have
 | 
			
		||||
    cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
 | 
			
		||||
      .its('body.0') // yields the first element of the returned list
 | 
			
		||||
      .then((user) => {
 | 
			
		||||
        expect(user).property('id').to.be.a('number')
 | 
			
		||||
        expect(user).property('id').to.be.a('number');
 | 
			
		||||
        // make a new post on behalf of the user
 | 
			
		||||
        cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
 | 
			
		||||
          userId: user.id,
 | 
			
		||||
          title: 'Cypress Test Runner',
 | 
			
		||||
          body: 'Fast, easy and reliable testing for anything that runs in a browser.',
 | 
			
		||||
        })
 | 
			
		||||
        });
 | 
			
		||||
      })
 | 
			
		||||
      // note that the value here is the returned value of the 2nd request
 | 
			
		||||
      // which is the new post object
 | 
			
		||||
      .then((response) => {
 | 
			
		||||
        expect(response).property('status').to.equal(201) // new entity created
 | 
			
		||||
        expect(response).property('status').to.equal(201); // new entity created
 | 
			
		||||
        expect(response).property('body').to.contain({
 | 
			
		||||
          id: 101, // there are already 100 posts, so new entity gets id 101
 | 
			
		||||
          title: 'Cypress Test Runner',
 | 
			
		||||
        })
 | 
			
		||||
        });
 | 
			
		||||
        // we don't know the user id here - since it was in above closure
 | 
			
		||||
        // so in this test just confirm that the property is there
 | 
			
		||||
        expect(response.body).property('userId').to.be.a('number')
 | 
			
		||||
      })
 | 
			
		||||
  })
 | 
			
		||||
        expect(response.body).property('userId').to.be.a('number');
 | 
			
		||||
      });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.request() - save response in the shared test context', () => {
 | 
			
		||||
    // https://on.cypress.io/variables-and-aliases
 | 
			
		||||
@@ -131,47 +128,48 @@ context('Network Requests', () => {
 | 
			
		||||
          title: 'Cypress Test Runner',
 | 
			
		||||
          body: 'Fast, easy and reliable testing for anything that runs in a browser.',
 | 
			
		||||
        })
 | 
			
		||||
        .its('body').as('post') // save the new post from the response
 | 
			
		||||
          .its('body')
 | 
			
		||||
          .as('post'); // save the new post from the response
 | 
			
		||||
      })
 | 
			
		||||
      .then(function () {
 | 
			
		||||
        // When this callback runs, both "cy.request" API commands have finished
 | 
			
		||||
        // and the test context has "user" and "post" objects set.
 | 
			
		||||
        // Let's verify them.
 | 
			
		||||
        expect(this.post, 'post has the right user id').property('userId').to.equal(this.user.id)
 | 
			
		||||
      })
 | 
			
		||||
  })
 | 
			
		||||
        expect(this.post, 'post has the right user id').property('userId').to.equal(this.user.id);
 | 
			
		||||
      });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.route() - route responses to matching requests', () => {
 | 
			
		||||
    // https://on.cypress.io/route
 | 
			
		||||
 | 
			
		||||
    let message = 'whoa, this comment does not exist'
 | 
			
		||||
    let message = 'whoa, this comment does not exist';
 | 
			
		||||
 | 
			
		||||
    cy.server()
 | 
			
		||||
    cy.server();
 | 
			
		||||
 | 
			
		||||
    // Listen to GET to comments/1
 | 
			
		||||
    cy.route('GET', 'comments/*').as('getComment')
 | 
			
		||||
    cy.route('GET', 'comments/*').as('getComment');
 | 
			
		||||
 | 
			
		||||
    // we have code that gets a comment when
 | 
			
		||||
    // the button is clicked in scripts.js
 | 
			
		||||
    cy.get('.network-btn').click()
 | 
			
		||||
    cy.get('.network-btn').click();
 | 
			
		||||
 | 
			
		||||
    // https://on.cypress.io/wait
 | 
			
		||||
    cy.wait('@getComment').its('status').should('eq', 200)
 | 
			
		||||
    cy.wait('@getComment').its('status').should('eq', 200);
 | 
			
		||||
 | 
			
		||||
    // Listen to POST to comments
 | 
			
		||||
    cy.route('POST', '/comments').as('postComment')
 | 
			
		||||
    cy.route('POST', '/comments').as('postComment');
 | 
			
		||||
 | 
			
		||||
    // we have code that posts a comment when
 | 
			
		||||
    // the button is clicked in scripts.js
 | 
			
		||||
    cy.get('.network-post').click()
 | 
			
		||||
    cy.wait('@postComment')
 | 
			
		||||
    cy.get('.network-post').click();
 | 
			
		||||
    cy.wait('@postComment');
 | 
			
		||||
 | 
			
		||||
    // get the route
 | 
			
		||||
    cy.get('@postComment').should((xhr) => {
 | 
			
		||||
      expect(xhr.requestBody).to.include('email')
 | 
			
		||||
      expect(xhr.requestHeaders).to.have.property('Content-Type')
 | 
			
		||||
      expect(xhr.responseBody).to.have.property('name', 'Using POST in cy.route()')
 | 
			
		||||
    })
 | 
			
		||||
      expect(xhr.requestBody).to.include('email');
 | 
			
		||||
      expect(xhr.requestHeaders).to.have.property('Content-Type');
 | 
			
		||||
      expect(xhr.responseBody).to.have.property('name', 'Using POST in cy.route()');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Stub a response to PUT comments/ ****
 | 
			
		||||
    cy.route({
 | 
			
		||||
@@ -180,15 +178,15 @@ context('Network Requests', () => {
 | 
			
		||||
      status: 404,
 | 
			
		||||
      response: { error: message },
 | 
			
		||||
      delay: 500,
 | 
			
		||||
    }).as('putComment')
 | 
			
		||||
    }).as('putComment');
 | 
			
		||||
 | 
			
		||||
    // we have code that puts a comment when
 | 
			
		||||
    // the button is clicked in scripts.js
 | 
			
		||||
    cy.get('.network-put').click()
 | 
			
		||||
    cy.get('.network-put').click();
 | 
			
		||||
 | 
			
		||||
    cy.wait('@putComment')
 | 
			
		||||
    cy.wait('@putComment');
 | 
			
		||||
 | 
			
		||||
    // our 404 statusCode logic in scripts.js executed
 | 
			
		||||
    cy.get('.network-put-comment').should('contain', message)
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    cy.get('.network-put-comment').should('contain', message);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,8 @@
 | 
			
		||||
 | 
			
		||||
context('Querying', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/querying')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/querying');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // The most commonly used query is 'cy.get()', you can
 | 
			
		||||
  // think of this like the '$' in jQuery
 | 
			
		||||
@@ -11,77 +11,65 @@ context('Querying', () => {
 | 
			
		||||
  it('cy.get() - query DOM elements', () => {
 | 
			
		||||
    // https://on.cypress.io/get
 | 
			
		||||
 | 
			
		||||
    cy.get('#query-btn').should('contain', 'Button')
 | 
			
		||||
    cy.get('#query-btn').should('contain', 'Button');
 | 
			
		||||
 | 
			
		||||
    cy.get('.query-btn').should('contain', 'Button')
 | 
			
		||||
    cy.get('.query-btn').should('contain', 'Button');
 | 
			
		||||
 | 
			
		||||
    cy.get('#querying .well>button:first').should('contain', 'Button')
 | 
			
		||||
    cy.get('#querying .well>button:first').should('contain', 'Button');
 | 
			
		||||
    //              ↲
 | 
			
		||||
    // Use CSS selectors just like jQuery
 | 
			
		||||
 | 
			
		||||
    cy.get('[data-test-id="test-example"]').should('have.class', 'example')
 | 
			
		||||
    cy.get('[data-test-id="test-example"]').should('have.class', 'example');
 | 
			
		||||
 | 
			
		||||
    // 'cy.get()' yields jQuery object, you can get its attribute
 | 
			
		||||
    // by invoking `.attr()` method
 | 
			
		||||
    cy.get('[data-test-id="test-example"]')
 | 
			
		||||
      .invoke('attr', 'data-test-id')
 | 
			
		||||
      .should('equal', 'test-example')
 | 
			
		||||
      .should('equal', 'test-example');
 | 
			
		||||
 | 
			
		||||
    // or you can get element's CSS property
 | 
			
		||||
    cy.get('[data-test-id="test-example"]')
 | 
			
		||||
      .invoke('css', 'position')
 | 
			
		||||
      .should('equal', 'static')
 | 
			
		||||
    cy.get('[data-test-id="test-example"]').invoke('css', 'position').should('equal', 'static');
 | 
			
		||||
 | 
			
		||||
    // or use assertions directly during 'cy.get()'
 | 
			
		||||
    // https://on.cypress.io/assertions
 | 
			
		||||
    cy.get('[data-test-id="test-example"]')
 | 
			
		||||
      .should('have.attr', 'data-test-id', 'test-example')
 | 
			
		||||
      .and('have.css', 'position', 'static')
 | 
			
		||||
  })
 | 
			
		||||
      .and('have.css', 'position', 'static');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.contains() - query DOM elements with matching content', () => {
 | 
			
		||||
    // https://on.cypress.io/contains
 | 
			
		||||
    cy.get('.query-list')
 | 
			
		||||
      .contains('bananas')
 | 
			
		||||
      .should('have.class', 'third')
 | 
			
		||||
    cy.get('.query-list').contains('bananas').should('have.class', 'third');
 | 
			
		||||
 | 
			
		||||
    // we can pass a regexp to `.contains()`
 | 
			
		||||
    cy.get('.query-list')
 | 
			
		||||
      .contains(/^b\w+/)
 | 
			
		||||
      .should('have.class', 'third')
 | 
			
		||||
    cy.get('.query-list').contains(/^b\w+/).should('have.class', 'third');
 | 
			
		||||
 | 
			
		||||
    cy.get('.query-list')
 | 
			
		||||
      .contains('apples')
 | 
			
		||||
      .should('have.class', 'first')
 | 
			
		||||
    cy.get('.query-list').contains('apples').should('have.class', 'first');
 | 
			
		||||
 | 
			
		||||
    // passing a selector to contains will
 | 
			
		||||
    // yield the selector containing the text
 | 
			
		||||
    cy.get('#querying')
 | 
			
		||||
      .contains('ul', 'oranges')
 | 
			
		||||
      .should('have.class', 'query-list')
 | 
			
		||||
    cy.get('#querying').contains('ul', 'oranges').should('have.class', 'query-list');
 | 
			
		||||
 | 
			
		||||
    cy.get('.query-button')
 | 
			
		||||
      .contains('Save Form')
 | 
			
		||||
      .should('have.class', 'btn')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.query-button').contains('Save Form').should('have.class', 'btn');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.within() - query DOM elements within a specific element', () => {
 | 
			
		||||
    // https://on.cypress.io/within
 | 
			
		||||
    cy.get('.query-form').within(() => {
 | 
			
		||||
      cy.get('input:first').should('have.attr', 'placeholder', 'Email')
 | 
			
		||||
      cy.get('input:last').should('have.attr', 'placeholder', 'Password')
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
      cy.get('input:first').should('have.attr', 'placeholder', 'Email');
 | 
			
		||||
      cy.get('input:last').should('have.attr', 'placeholder', 'Password');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.root() - query the root DOM element', () => {
 | 
			
		||||
    // https://on.cypress.io/root
 | 
			
		||||
 | 
			
		||||
    // By default, root is the document
 | 
			
		||||
    cy.root().should('match', 'html')
 | 
			
		||||
    cy.root().should('match', 'html');
 | 
			
		||||
 | 
			
		||||
    cy.get('.query-ul').within(() => {
 | 
			
		||||
      // In this within, the root is now the ul DOM element
 | 
			
		||||
      cy.root().should('have.class', 'query-ul')
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
      cy.root().should('have.class', 'query-ul');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -3,93 +3,92 @@
 | 
			
		||||
context('Spies, Stubs, and Clock', () => {
 | 
			
		||||
  it('cy.spy() - wrap a method in a spy', () => {
 | 
			
		||||
    // https://on.cypress.io/spy
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
 | 
			
		||||
 | 
			
		||||
    const obj = {
 | 
			
		||||
      foo () {},
 | 
			
		||||
    }
 | 
			
		||||
      foo() {},
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const spy = cy.spy(obj, 'foo').as('anyArgs')
 | 
			
		||||
    const spy = cy.spy(obj, 'foo').as('anyArgs');
 | 
			
		||||
 | 
			
		||||
    obj.foo()
 | 
			
		||||
    obj.foo();
 | 
			
		||||
 | 
			
		||||
    expect(spy).to.be.called
 | 
			
		||||
  })
 | 
			
		||||
    expect(spy).to.be.called;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.spy() retries until assertions pass', () => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
 | 
			
		||||
 | 
			
		||||
    const obj = {
 | 
			
		||||
      /**
 | 
			
		||||
       * Prints the argument passed
 | 
			
		||||
       *
 | 
			
		||||
       * @param x {any}
 | 
			
		||||
      */
 | 
			
		||||
      foo (x) {
 | 
			
		||||
        console.log('obj.foo called with', x)
 | 
			
		||||
       */
 | 
			
		||||
      foo(x) {
 | 
			
		||||
        console.log('obj.foo called with', x);
 | 
			
		||||
      },
 | 
			
		||||
    }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    cy.spy(obj, 'foo').as('foo')
 | 
			
		||||
    cy.spy(obj, 'foo').as('foo');
 | 
			
		||||
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
      obj.foo('first')
 | 
			
		||||
    }, 500)
 | 
			
		||||
      obj.foo('first');
 | 
			
		||||
    }, 500);
 | 
			
		||||
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
      obj.foo('second')
 | 
			
		||||
    }, 2500)
 | 
			
		||||
      obj.foo('second');
 | 
			
		||||
    }, 2500);
 | 
			
		||||
 | 
			
		||||
    cy.get('@foo').should('have.been.calledTwice')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('@foo').should('have.been.calledTwice');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.stub() - create a stub and/or replace a function with stub', () => {
 | 
			
		||||
    // https://on.cypress.io/stub
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
 | 
			
		||||
 | 
			
		||||
    const obj = {
 | 
			
		||||
      /**
 | 
			
		||||
       * prints both arguments to the console
 | 
			
		||||
       * Prints both arguments to the console
 | 
			
		||||
       *
 | 
			
		||||
       * @param a {string}
 | 
			
		||||
       * @param b {string}
 | 
			
		||||
      */
 | 
			
		||||
      foo (a, b) {
 | 
			
		||||
        console.log('a', a, 'b', b)
 | 
			
		||||
       */
 | 
			
		||||
      foo(a, b) {
 | 
			
		||||
        console.log('a', a, 'b', b);
 | 
			
		||||
      },
 | 
			
		||||
    }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const stub = cy.stub(obj, 'foo').as('foo')
 | 
			
		||||
    const stub = cy.stub(obj, 'foo').as('foo');
 | 
			
		||||
 | 
			
		||||
    obj.foo('foo', 'bar')
 | 
			
		||||
    obj.foo('foo', 'bar');
 | 
			
		||||
 | 
			
		||||
    expect(stub).to.be.called
 | 
			
		||||
  })
 | 
			
		||||
    expect(stub).to.be.called;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.clock() - control time in the browser', () => {
 | 
			
		||||
    // https://on.cypress.io/clock
 | 
			
		||||
 | 
			
		||||
    // create the date in UTC so its always the same
 | 
			
		||||
    // no matter what local timezone the browser is running in
 | 
			
		||||
    const now = new Date(Date.UTC(2017, 2, 14)).getTime()
 | 
			
		||||
    const now = new Date(Date.UTC(2017, 2, 14)).getTime();
 | 
			
		||||
 | 
			
		||||
    cy.clock(now)
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
 | 
			
		||||
    cy.get('#clock-div').click()
 | 
			
		||||
      .should('have.text', '1489449600')
 | 
			
		||||
  })
 | 
			
		||||
    cy.clock(now);
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
 | 
			
		||||
    cy.get('#clock-div').click().should('have.text', '1489449600');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.tick() - move time in the browser', () => {
 | 
			
		||||
    // https://on.cypress.io/tick
 | 
			
		||||
 | 
			
		||||
    // create the date in UTC so its always the same
 | 
			
		||||
    // no matter what local timezone the browser is running in
 | 
			
		||||
    const now = new Date(Date.UTC(2017, 2, 14)).getTime()
 | 
			
		||||
    const now = new Date(Date.UTC(2017, 2, 14)).getTime();
 | 
			
		||||
 | 
			
		||||
    cy.clock(now)
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
 | 
			
		||||
    cy.get('#tick-div').click()
 | 
			
		||||
      .should('have.text', '1489449600')
 | 
			
		||||
    cy.tick(10000) // 10 seconds passed
 | 
			
		||||
    cy.get('#tick-div').click()
 | 
			
		||||
      .should('have.text', '1489449610')
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    cy.clock(now);
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
 | 
			
		||||
    cy.get('#tick-div').click().should('have.text', '1489449600');
 | 
			
		||||
    cy.tick(10000); // 10 seconds passed
 | 
			
		||||
    cy.get('#tick-div').click().should('have.text', '1489449610');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,120 +2,96 @@
 | 
			
		||||
 | 
			
		||||
context('Traversal', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/traversal')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/traversal');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.children() - get child DOM elements', () => {
 | 
			
		||||
    // https://on.cypress.io/children
 | 
			
		||||
    cy.get('.traversal-breadcrumb')
 | 
			
		||||
      .children('.active')
 | 
			
		||||
      .should('contain', 'Data')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.traversal-breadcrumb').children('.active').should('contain', 'Data');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.closest() - get closest ancestor DOM element', () => {
 | 
			
		||||
    // https://on.cypress.io/closest
 | 
			
		||||
    cy.get('.traversal-badge')
 | 
			
		||||
      .closest('ul')
 | 
			
		||||
      .should('have.class', 'list-group')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.traversal-badge').closest('ul').should('have.class', 'list-group');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.eq() - get a DOM element at a specific index', () => {
 | 
			
		||||
    // https://on.cypress.io/eq
 | 
			
		||||
    cy.get('.traversal-list>li')
 | 
			
		||||
      .eq(1).should('contain', 'siamese')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.traversal-list>li').eq(1).should('contain', 'siamese');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.filter() - get DOM elements that match the selector', () => {
 | 
			
		||||
    // https://on.cypress.io/filter
 | 
			
		||||
    cy.get('.traversal-nav>li')
 | 
			
		||||
      .filter('.active').should('contain', 'About')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.traversal-nav>li').filter('.active').should('contain', 'About');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.find() - get descendant DOM elements of the selector', () => {
 | 
			
		||||
    // https://on.cypress.io/find
 | 
			
		||||
    cy.get('.traversal-pagination')
 | 
			
		||||
      .find('li').find('a')
 | 
			
		||||
      .should('have.length', 7)
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.traversal-pagination').find('li').find('a').should('have.length', 7);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.first() - get first DOM element', () => {
 | 
			
		||||
    // https://on.cypress.io/first
 | 
			
		||||
    cy.get('.traversal-table td')
 | 
			
		||||
      .first().should('contain', '1')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.traversal-table td').first().should('contain', '1');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.last() - get last DOM element', () => {
 | 
			
		||||
    // https://on.cypress.io/last
 | 
			
		||||
    cy.get('.traversal-buttons .btn')
 | 
			
		||||
      .last().should('contain', 'Submit')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.traversal-buttons .btn').last().should('contain', 'Submit');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.next() - get next sibling DOM element', () => {
 | 
			
		||||
    // https://on.cypress.io/next
 | 
			
		||||
    cy.get('.traversal-ul')
 | 
			
		||||
      .contains('apples').next().should('contain', 'oranges')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.traversal-ul').contains('apples').next().should('contain', 'oranges');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.nextAll() - get all next sibling DOM elements', () => {
 | 
			
		||||
    // https://on.cypress.io/nextall
 | 
			
		||||
    cy.get('.traversal-next-all')
 | 
			
		||||
      .contains('oranges')
 | 
			
		||||
      .nextAll().should('have.length', 3)
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.traversal-next-all').contains('oranges').nextAll().should('have.length', 3);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.nextUntil() - get next sibling DOM elements until next el', () => {
 | 
			
		||||
    // https://on.cypress.io/nextuntil
 | 
			
		||||
    cy.get('#veggies')
 | 
			
		||||
      .nextUntil('#nuts').should('have.length', 3)
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('#veggies').nextUntil('#nuts').should('have.length', 3);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.not() - remove DOM elements from set of DOM elements', () => {
 | 
			
		||||
    // https://on.cypress.io/not
 | 
			
		||||
    cy.get('.traversal-disabled .btn')
 | 
			
		||||
      .not('[disabled]').should('not.contain', 'Disabled')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.traversal-disabled .btn').not('[disabled]').should('not.contain', 'Disabled');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.parent() - get parent DOM element from DOM elements', () => {
 | 
			
		||||
    // https://on.cypress.io/parent
 | 
			
		||||
    cy.get('.traversal-mark')
 | 
			
		||||
      .parent().should('contain', 'Morbi leo risus')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.traversal-mark').parent().should('contain', 'Morbi leo risus');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.parents() - get parent DOM elements from DOM elements', () => {
 | 
			
		||||
    // https://on.cypress.io/parents
 | 
			
		||||
    cy.get('.traversal-cite')
 | 
			
		||||
      .parents().should('match', 'blockquote')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.traversal-cite').parents().should('match', 'blockquote');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.parentsUntil() - get parent DOM elements from DOM elements until el', () => {
 | 
			
		||||
    // https://on.cypress.io/parentsuntil
 | 
			
		||||
    cy.get('.clothes-nav')
 | 
			
		||||
      .find('.active')
 | 
			
		||||
      .parentsUntil('.clothes-nav')
 | 
			
		||||
      .should('have.length', 2)
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.clothes-nav').find('.active').parentsUntil('.clothes-nav').should('have.length', 2);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.prev() - get previous sibling DOM element', () => {
 | 
			
		||||
    // https://on.cypress.io/prev
 | 
			
		||||
    cy.get('.birds').find('.active')
 | 
			
		||||
      .prev().should('contain', 'Lorikeets')
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.birds').find('.active').prev().should('contain', 'Lorikeets');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.prevAll() - get all previous sibling DOM elements', () => {
 | 
			
		||||
    // https://on.cypress.io/prevAll
 | 
			
		||||
    cy.get('.fruits-list').find('.third')
 | 
			
		||||
      .prevAll().should('have.length', 2)
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.fruits-list').find('.third').prevAll().should('have.length', 2);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.prevUntil() - get all previous sibling DOM elements until el', () => {
 | 
			
		||||
    // https://on.cypress.io/prevUntil
 | 
			
		||||
    cy.get('.foods-list').find('#nuts')
 | 
			
		||||
      .prevUntil('#veggies').should('have.length', 3)
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.foods-list').find('#nuts').prevUntil('#veggies').should('have.length', 3);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('.siblings() - get all sibling DOM elements', () => {
 | 
			
		||||
    // https://on.cypress.io/siblings
 | 
			
		||||
    cy.get('.traversal-pills .active')
 | 
			
		||||
      .siblings().should('have.length', 2)
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    cy.get('.traversal-pills .active').siblings().should('have.length', 2);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,132 +2,128 @@
 | 
			
		||||
 | 
			
		||||
context('Utilities', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/utilities')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/utilities');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('Cypress._ - call a lodash method', () => {
 | 
			
		||||
    // https://on.cypress.io/_
 | 
			
		||||
    cy.request('https://jsonplaceholder.cypress.io/users')
 | 
			
		||||
      .then((response) => {
 | 
			
		||||
        let ids = Cypress._.chain(response.body).map('id').take(3).value()
 | 
			
		||||
    cy.request('https://jsonplaceholder.cypress.io/users').then((response) => {
 | 
			
		||||
      let ids = Cypress._.chain(response.body).map('id').take(3).value();
 | 
			
		||||
 | 
			
		||||
        expect(ids).to.deep.eq([1, 2, 3])
 | 
			
		||||
      })
 | 
			
		||||
  })
 | 
			
		||||
      expect(ids).to.deep.eq([1, 2, 3]);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('Cypress.$ - call a jQuery method', () => {
 | 
			
		||||
    // https://on.cypress.io/$
 | 
			
		||||
    let $li = Cypress.$('.utility-jquery li:first')
 | 
			
		||||
    let $li = Cypress.$('.utility-jquery li:first');
 | 
			
		||||
 | 
			
		||||
    cy.wrap($li)
 | 
			
		||||
      .should('not.have.class', 'active')
 | 
			
		||||
      .click()
 | 
			
		||||
      .should('have.class', 'active')
 | 
			
		||||
  })
 | 
			
		||||
    cy.wrap($li).should('not.have.class', 'active').click().should('have.class', 'active');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('Cypress.Blob - blob utilities and base64 string conversion', () => {
 | 
			
		||||
    // https://on.cypress.io/blob
 | 
			
		||||
    cy.get('.utility-blob').then(($div) =>
 | 
			
		||||
    // https://github.com/nolanlawson/blob-util#imgSrcToDataURL
 | 
			
		||||
    // get the dataUrl string for the javascript-logo
 | 
			
		||||
      Cypress.Blob.imgSrcToDataURL('https://example.cypress.io/assets/img/javascript-logo.png', undefined, 'anonymous')
 | 
			
		||||
      .then((dataUrl) => {
 | 
			
		||||
      // https://github.com/nolanlawson/blob-util#imgSrcToDataURL
 | 
			
		||||
      // get the dataUrl string for the javascript-logo
 | 
			
		||||
      Cypress.Blob.imgSrcToDataURL(
 | 
			
		||||
        'https://example.cypress.io/assets/img/javascript-logo.png',
 | 
			
		||||
        undefined,
 | 
			
		||||
        'anonymous'
 | 
			
		||||
      ).then((dataUrl) => {
 | 
			
		||||
        // create an <img> element and set its src to the dataUrl
 | 
			
		||||
        let img = Cypress.$('<img />', { src: dataUrl })
 | 
			
		||||
        let img = Cypress.$('<img />', { src: dataUrl });
 | 
			
		||||
 | 
			
		||||
        // need to explicitly return cy here since we are initially returning
 | 
			
		||||
        // the Cypress.Blob.imgSrcToDataURL promise to our test
 | 
			
		||||
        // append the image
 | 
			
		||||
        $div.append(img)
 | 
			
		||||
        $div.append(img);
 | 
			
		||||
 | 
			
		||||
        cy.get('.utility-blob img').click()
 | 
			
		||||
          .should('have.attr', 'src', dataUrl)
 | 
			
		||||
      }))
 | 
			
		||||
  })
 | 
			
		||||
        cy.get('.utility-blob img').click().should('have.attr', 'src', dataUrl);
 | 
			
		||||
      })
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('Cypress.minimatch - test out glob patterns against strings', () => {
 | 
			
		||||
    // https://on.cypress.io/minimatch
 | 
			
		||||
    let matching = Cypress.minimatch('/users/1/comments', '/users/*/comments', {
 | 
			
		||||
      matchBase: true,
 | 
			
		||||
    })
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    expect(matching, 'matching wildcard').to.be.true
 | 
			
		||||
    expect(matching, 'matching wildcard').to.be.true;
 | 
			
		||||
 | 
			
		||||
    matching = Cypress.minimatch('/users/1/comments/2', '/users/*/comments', {
 | 
			
		||||
      matchBase: true,
 | 
			
		||||
    })
 | 
			
		||||
    expect(matching, 'comments').to.be.false
 | 
			
		||||
    });
 | 
			
		||||
    expect(matching, 'comments').to.be.false;
 | 
			
		||||
 | 
			
		||||
    // ** matches against all downstream path segments
 | 
			
		||||
    matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/**', {
 | 
			
		||||
      matchBase: true,
 | 
			
		||||
    })
 | 
			
		||||
    expect(matching, 'comments').to.be.true
 | 
			
		||||
    });
 | 
			
		||||
    expect(matching, 'comments').to.be.true;
 | 
			
		||||
 | 
			
		||||
    // whereas * matches only the next path segment
 | 
			
		||||
 | 
			
		||||
    matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/*', {
 | 
			
		||||
      matchBase: false,
 | 
			
		||||
    })
 | 
			
		||||
    expect(matching, 'comments').to.be.false
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
    expect(matching, 'comments').to.be.false;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('Cypress.moment() - format or parse dates using a moment method', () => {
 | 
			
		||||
    // https://on.cypress.io/moment
 | 
			
		||||
    const time = Cypress.moment().utc('2014-04-25T19:38:53.196Z').format('h:mm A')
 | 
			
		||||
    const time = Cypress.moment().utc('2014-04-25T19:38:53.196Z').format('h:mm A');
 | 
			
		||||
 | 
			
		||||
    expect(time).to.be.a('string')
 | 
			
		||||
    expect(time).to.be.a('string');
 | 
			
		||||
 | 
			
		||||
    cy.get('.utility-moment').contains('3:38 PM')
 | 
			
		||||
      .should('have.class', 'badge')
 | 
			
		||||
    cy.get('.utility-moment').contains('3:38 PM').should('have.class', 'badge');
 | 
			
		||||
 | 
			
		||||
    // the time in the element should be between 3pm and 5pm
 | 
			
		||||
    const start = Cypress.moment('3:00 PM', 'LT')
 | 
			
		||||
    const end = Cypress.moment('5:00 PM', 'LT')
 | 
			
		||||
    const start = Cypress.moment('3:00 PM', 'LT');
 | 
			
		||||
    const end = Cypress.moment('5:00 PM', 'LT');
 | 
			
		||||
 | 
			
		||||
    cy.get('.utility-moment .badge')
 | 
			
		||||
      .should(($el) => {
 | 
			
		||||
        // parse American time like "3:38 PM"
 | 
			
		||||
        const m = Cypress.moment($el.text().trim(), 'LT')
 | 
			
		||||
    cy.get('.utility-moment .badge').should(($el) => {
 | 
			
		||||
      // parse American time like "3:38 PM"
 | 
			
		||||
      const m = Cypress.moment($el.text().trim(), 'LT');
 | 
			
		||||
 | 
			
		||||
        // display hours + minutes + AM|PM
 | 
			
		||||
        const f = 'h:mm A'
 | 
			
		||||
 | 
			
		||||
        expect(m.isBetween(start, end),
 | 
			
		||||
          `${m.format(f)} should be between ${start.format(f)} and ${end.format(f)}`).to.be.true
 | 
			
		||||
      })
 | 
			
		||||
  })
 | 
			
		||||
      // display hours + minutes + AM|PM
 | 
			
		||||
      const f = 'h:mm A';
 | 
			
		||||
 | 
			
		||||
      expect(
 | 
			
		||||
        m.isBetween(start, end),
 | 
			
		||||
        `${m.format(f)} should be between ${start.format(f)} and ${end.format(f)}`
 | 
			
		||||
      ).to.be.true;
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('Cypress.Promise - instantiate a bluebird promise', () => {
 | 
			
		||||
    // https://on.cypress.io/promise
 | 
			
		||||
    let waited = false
 | 
			
		||||
    let waited = false;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return Bluebird<string>
 | 
			
		||||
     */
 | 
			
		||||
    function waitOneSecond () {
 | 
			
		||||
    /** @returns Bluebird<string> */
 | 
			
		||||
    function waitOneSecond() {
 | 
			
		||||
      // return a promise that resolves after 1 second
 | 
			
		||||
      // @ts-ignore TS2351 (new Cypress.Promise)
 | 
			
		||||
      return new Cypress.Promise((resolve, reject) => {
 | 
			
		||||
        setTimeout(() => {
 | 
			
		||||
          // set waited to true
 | 
			
		||||
          waited = true
 | 
			
		||||
          waited = true;
 | 
			
		||||
 | 
			
		||||
          // resolve with 'foo' string
 | 
			
		||||
          resolve('foo')
 | 
			
		||||
        }, 1000)
 | 
			
		||||
      })
 | 
			
		||||
          resolve('foo');
 | 
			
		||||
        }, 1000);
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cy.then(() =>
 | 
			
		||||
    // return a promise to cy.then() that
 | 
			
		||||
    // is awaited until it resolves
 | 
			
		||||
      // return a promise to cy.then() that
 | 
			
		||||
      // is awaited until it resolves
 | 
			
		||||
      // @ts-ignore TS7006
 | 
			
		||||
      waitOneSecond().then((str) => {
 | 
			
		||||
        expect(str).to.eq('foo')
 | 
			
		||||
        expect(waited).to.be.true
 | 
			
		||||
      }))
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
        expect(str).to.eq('foo');
 | 
			
		||||
        expect(waited).to.be.true;
 | 
			
		||||
      })
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,22 +2,22 @@
 | 
			
		||||
 | 
			
		||||
context('Viewport', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/viewport')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/viewport');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.viewport() - set the viewport size and dimension', () => {
 | 
			
		||||
    // https://on.cypress.io/viewport
 | 
			
		||||
 | 
			
		||||
    cy.get('#navbar').should('be.visible')
 | 
			
		||||
    cy.viewport(320, 480)
 | 
			
		||||
    cy.get('#navbar').should('be.visible');
 | 
			
		||||
    cy.viewport(320, 480);
 | 
			
		||||
 | 
			
		||||
    // the navbar should have collapse since our screen is smaller
 | 
			
		||||
    cy.get('#navbar').should('not.be.visible')
 | 
			
		||||
    cy.get('.navbar-toggle').should('be.visible').click()
 | 
			
		||||
    cy.get('.nav').find('a').should('be.visible')
 | 
			
		||||
    cy.get('#navbar').should('not.be.visible');
 | 
			
		||||
    cy.get('.navbar-toggle').should('be.visible').click();
 | 
			
		||||
    cy.get('.nav').find('a').should('be.visible');
 | 
			
		||||
 | 
			
		||||
    // lets see what our app looks like on a super large screen
 | 
			
		||||
    cy.viewport(2999, 2999)
 | 
			
		||||
    cy.viewport(2999, 2999);
 | 
			
		||||
 | 
			
		||||
    // cy.viewport() accepts a set of preset sizes
 | 
			
		||||
    // to easily set the screen to a device's width and height
 | 
			
		||||
@@ -25,35 +25,35 @@ context('Viewport', () => {
 | 
			
		||||
    // We added a cy.wait() between each viewport change so you can see
 | 
			
		||||
    // the change otherwise it is a little too fast to see :)
 | 
			
		||||
 | 
			
		||||
    cy.viewport('macbook-15')
 | 
			
		||||
    cy.wait(200)
 | 
			
		||||
    cy.viewport('macbook-13')
 | 
			
		||||
    cy.wait(200)
 | 
			
		||||
    cy.viewport('macbook-11')
 | 
			
		||||
    cy.wait(200)
 | 
			
		||||
    cy.viewport('ipad-2')
 | 
			
		||||
    cy.wait(200)
 | 
			
		||||
    cy.viewport('ipad-mini')
 | 
			
		||||
    cy.wait(200)
 | 
			
		||||
    cy.viewport('iphone-6+')
 | 
			
		||||
    cy.wait(200)
 | 
			
		||||
    cy.viewport('iphone-6')
 | 
			
		||||
    cy.wait(200)
 | 
			
		||||
    cy.viewport('iphone-5')
 | 
			
		||||
    cy.wait(200)
 | 
			
		||||
    cy.viewport('iphone-4')
 | 
			
		||||
    cy.wait(200)
 | 
			
		||||
    cy.viewport('iphone-3')
 | 
			
		||||
    cy.wait(200)
 | 
			
		||||
    cy.viewport('macbook-15');
 | 
			
		||||
    cy.wait(200);
 | 
			
		||||
    cy.viewport('macbook-13');
 | 
			
		||||
    cy.wait(200);
 | 
			
		||||
    cy.viewport('macbook-11');
 | 
			
		||||
    cy.wait(200);
 | 
			
		||||
    cy.viewport('ipad-2');
 | 
			
		||||
    cy.wait(200);
 | 
			
		||||
    cy.viewport('ipad-mini');
 | 
			
		||||
    cy.wait(200);
 | 
			
		||||
    cy.viewport('iphone-6+');
 | 
			
		||||
    cy.wait(200);
 | 
			
		||||
    cy.viewport('iphone-6');
 | 
			
		||||
    cy.wait(200);
 | 
			
		||||
    cy.viewport('iphone-5');
 | 
			
		||||
    cy.wait(200);
 | 
			
		||||
    cy.viewport('iphone-4');
 | 
			
		||||
    cy.wait(200);
 | 
			
		||||
    cy.viewport('iphone-3');
 | 
			
		||||
    cy.wait(200);
 | 
			
		||||
 | 
			
		||||
    // cy.viewport() accepts an orientation for all presets
 | 
			
		||||
    // the default orientation is 'portrait'
 | 
			
		||||
    cy.viewport('ipad-2', 'portrait')
 | 
			
		||||
    cy.wait(200)
 | 
			
		||||
    cy.viewport('iphone-4', 'landscape')
 | 
			
		||||
    cy.wait(200)
 | 
			
		||||
    cy.viewport('ipad-2', 'portrait');
 | 
			
		||||
    cy.wait(200);
 | 
			
		||||
    cy.viewport('iphone-4', 'landscape');
 | 
			
		||||
    cy.wait(200);
 | 
			
		||||
 | 
			
		||||
    // The viewport will be reset back to the default dimensions
 | 
			
		||||
    // in between tests (the  default can be set in cypress.json)
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,33 +2,32 @@
 | 
			
		||||
 | 
			
		||||
context('Waiting', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/waiting')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/waiting');
 | 
			
		||||
  });
 | 
			
		||||
  // BE CAREFUL of adding unnecessary wait times.
 | 
			
		||||
  // https://on.cypress.io/best-practices#Unnecessary-Waiting
 | 
			
		||||
 | 
			
		||||
  // https://on.cypress.io/wait
 | 
			
		||||
  it('cy.wait() - wait for a specific amount of time', () => {
 | 
			
		||||
    cy.get('.wait-input1').type('Wait 1000ms after typing')
 | 
			
		||||
    cy.wait(1000)
 | 
			
		||||
    cy.get('.wait-input2').type('Wait 1000ms after typing')
 | 
			
		||||
    cy.wait(1000)
 | 
			
		||||
    cy.get('.wait-input3').type('Wait 1000ms after typing')
 | 
			
		||||
    cy.wait(1000)
 | 
			
		||||
  })
 | 
			
		||||
    cy.get('.wait-input1').type('Wait 1000ms after typing');
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('.wait-input2').type('Wait 1000ms after typing');
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('.wait-input3').type('Wait 1000ms after typing');
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.wait() - wait for a specific route', () => {
 | 
			
		||||
    cy.server()
 | 
			
		||||
    cy.server();
 | 
			
		||||
 | 
			
		||||
    // Listen to GET to comments/1
 | 
			
		||||
    cy.route('GET', 'comments/*').as('getComment')
 | 
			
		||||
    cy.route('GET', 'comments/*').as('getComment');
 | 
			
		||||
 | 
			
		||||
    // we have code that gets a comment when
 | 
			
		||||
    // the button is clicked in scripts.js
 | 
			
		||||
    cy.get('.network-btn').click()
 | 
			
		||||
    cy.get('.network-btn').click();
 | 
			
		||||
 | 
			
		||||
    // wait for GET comments/1
 | 
			
		||||
    cy.wait('@getComment').its('status').should('eq', 200)
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
    cy.wait('@getComment').its('status').should('eq', 200);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,21 +2,21 @@
 | 
			
		||||
 | 
			
		||||
context('Window', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/window')
 | 
			
		||||
  })
 | 
			
		||||
    cy.visit('https://example.cypress.io/commands/window');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.window() - get the global window object', () => {
 | 
			
		||||
    // https://on.cypress.io/window
 | 
			
		||||
    cy.window().should('have.property', 'top')
 | 
			
		||||
  })
 | 
			
		||||
    cy.window().should('have.property', 'top');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.document() - get the document object', () => {
 | 
			
		||||
    // https://on.cypress.io/document
 | 
			
		||||
    cy.document().should('have.property', 'charset').and('eq', 'UTF-8')
 | 
			
		||||
  })
 | 
			
		||||
    cy.document().should('have.property', 'charset').and('eq', 'UTF-8');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('cy.title() - get the title', () => {
 | 
			
		||||
    // https://on.cypress.io/title
 | 
			
		||||
    cy.title().should('include', 'Kitchen Sink')
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
    cy.title().should('include', 'Kitchen Sink');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "Using fixtures to represent data",
 | 
			
		||||
  "email": "hello@cypress.io",
 | 
			
		||||
  "body": "Fixtures are a great way to mock data for responses to routes"
 | 
			
		||||
{
 | 
			
		||||
  "name": "Using fixtures to represent data",
 | 
			
		||||
  "email": "hello@cypress.io",
 | 
			
		||||
  "body": "Fixtures are a great way to mock data for responses to routes"
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +1,9 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
/* global cy */
 | 
			
		||||
import { Base64 } from 'js-base64';
 | 
			
		||||
 | 
			
		||||
export const mermaidUrl = (graphStr, options, api) => {
 | 
			
		||||
  const obj = {
 | 
			
		||||
    code: graphStr,
 | 
			
		||||
    mermaid: options
 | 
			
		||||
    mermaid: options,
 | 
			
		||||
  };
 | 
			
		||||
  const objStr = JSON.stringify(obj);
 | 
			
		||||
  let url = 'http://localhost:9000/e2e.html?graph=' + Base64.encodeURI(objStr);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
import { renderGraph } from '../../helpers/util';
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
describe('Configuration', () => {
 | 
			
		||||
  describe('arrowMarkerAbsolute', () => {
 | 
			
		||||
    it('should handle default value false of arrowMarkerAbsolute', () => {
 | 
			
		||||
@@ -11,12 +10,14 @@ describe('Configuration', () => {
 | 
			
		||||
        C -->|Two| E[iPhone]
 | 
			
		||||
        C -->|Three| F[fa:fa-car Car]
 | 
			
		||||
        `,
 | 
			
		||||
        { }
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      // Check the marker-end property to make sure it is properly set to
 | 
			
		||||
      // start with #
 | 
			
		||||
      cy.get('.edgePath path').first().should('have.attr', 'marker-end')
 | 
			
		||||
      cy.get('.edgePath path')
 | 
			
		||||
        .first()
 | 
			
		||||
        .should('have.attr', 'marker-end')
 | 
			
		||||
        .should('exist')
 | 
			
		||||
        .and('include', 'url(#');
 | 
			
		||||
    });
 | 
			
		||||
@@ -29,12 +30,14 @@ describe('Configuration', () => {
 | 
			
		||||
        C -->|Two| E[iPhone]
 | 
			
		||||
        C -->|Three| F[fa:fa-car Car]
 | 
			
		||||
        `,
 | 
			
		||||
        { }
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      // Check the marker-end property to make sure it is properly set to
 | 
			
		||||
      // start with #
 | 
			
		||||
      cy.get('.edgePath path').first().should('have.attr', 'marker-end')
 | 
			
		||||
      cy.get('.edgePath path')
 | 
			
		||||
        .first()
 | 
			
		||||
        .should('have.attr', 'marker-end')
 | 
			
		||||
        .should('exist')
 | 
			
		||||
        .and('include', 'url(#');
 | 
			
		||||
    });
 | 
			
		||||
@@ -48,13 +51,15 @@ describe('Configuration', () => {
 | 
			
		||||
        C -->|Three| F[fa:fa-car Car]
 | 
			
		||||
        `,
 | 
			
		||||
        {
 | 
			
		||||
          arrowMarkerAbsolute: false
 | 
			
		||||
          arrowMarkerAbsolute: false,
 | 
			
		||||
        }
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      // Check the marker-end property to make sure it is properly set to
 | 
			
		||||
      // start with #
 | 
			
		||||
      cy.get('.edgePath path').first().should('have.attr', 'marker-end')
 | 
			
		||||
      cy.get('.edgePath path')
 | 
			
		||||
        .first()
 | 
			
		||||
        .should('have.attr', 'marker-end')
 | 
			
		||||
        .should('exist')
 | 
			
		||||
        .and('include', 'url(#');
 | 
			
		||||
    });
 | 
			
		||||
@@ -68,13 +73,15 @@ describe('Configuration', () => {
 | 
			
		||||
        C -->|Three| F[fa:fa-car Car]
 | 
			
		||||
        `,
 | 
			
		||||
        {
 | 
			
		||||
          arrowMarkerAbsolute: "false"
 | 
			
		||||
          arrowMarkerAbsolute: 'false',
 | 
			
		||||
        }
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      // Check the marker-end property to make sure it is properly set to
 | 
			
		||||
      // start with #
 | 
			
		||||
      cy.get('.edgePath path').first().should('have.attr', 'marker-end')
 | 
			
		||||
      cy.get('.edgePath path')
 | 
			
		||||
        .first()
 | 
			
		||||
        .should('have.attr', 'marker-end')
 | 
			
		||||
        .should('exist')
 | 
			
		||||
        .and('include', 'url(#');
 | 
			
		||||
    });
 | 
			
		||||
@@ -88,13 +95,23 @@ describe('Configuration', () => {
 | 
			
		||||
        C -->|Three| F[fa:fa-car Car]
 | 
			
		||||
        `,
 | 
			
		||||
        {
 | 
			
		||||
          arrowMarkerAbsolute: true
 | 
			
		||||
          arrowMarkerAbsolute: true,
 | 
			
		||||
        }
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      cy.get('.edgePath path').first().should('have.attr', 'marker-end')
 | 
			
		||||
      cy.get('.edgePath path')
 | 
			
		||||
        .first()
 | 
			
		||||
        .should('have.attr', 'marker-end')
 | 
			
		||||
        .should('exist')
 | 
			
		||||
        .and('include', 'url(http://localhost');
 | 
			
		||||
    });
 | 
			
		||||
    it('should not taint the initial configuration when using multiple directives', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/regression/issue-1874.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
 | 
			
		||||
      cy.get('svg');
 | 
			
		||||
      cy.percySnapshot();
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,35 +1,36 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
describe('Interaction', () => {
 | 
			
		||||
  describe('Interaction - security level loose', () => {
 | 
			
		||||
    it('Graph: should handle a click on a node with a bound function', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_loose.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('g#flowchart-Function-2')
 | 
			
		||||
        .click();
 | 
			
		||||
      cy.get('body').find('g#flowchart-Function-2').click();
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
 | 
			
		||||
    });
 | 
			
		||||
    it('Graph: should handle a click on a node with a bound function where the node starts with a number', () => {
 | 
			
		||||
    it('Graph: should handle a click on a node with a bound function with args', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_loose.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('g[id="flowchart-1Function-6"]')
 | 
			
		||||
        .click();
 | 
			
		||||
      cy.get('body').find('g#flowchart-FunctionArg-18').click();
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
 | 
			
		||||
      cy.get('.created-by-click-2').should('have.text', 'Clicked By Flow: ARGUMENT');
 | 
			
		||||
    });
 | 
			
		||||
    it('Flowchart: should handle a click on a node with a bound function where the node starts with a number', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_loose.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body').find('g[id="flowchart-FunctionArg-22"]').click();
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-click-2').should('have.text', 'Clicked By Flow: ARGUMENT');
 | 
			
		||||
    });
 | 
			
		||||
    it('Graph: should handle a click on a node with a bound url', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_loose.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('#flowchart-URL-3')
 | 
			
		||||
        .click();
 | 
			
		||||
      cy.get('body').find('#flowchart-URL-3').click();
 | 
			
		||||
 | 
			
		||||
      cy.location().should(location => {
 | 
			
		||||
      cy.location().should((location) => {
 | 
			
		||||
        expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -37,11 +38,9 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_loose.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('g[id="flowchart-2URL-7"]')
 | 
			
		||||
        .click();
 | 
			
		||||
      cy.get('body').find('g[id="flowchart-2URL-7"]').click();
 | 
			
		||||
 | 
			
		||||
      cy.location().should(location => {
 | 
			
		||||
      cy.location().should((location) => {
 | 
			
		||||
        expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -50,9 +49,7 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_loose.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('g#flowchart-Function-10')
 | 
			
		||||
        .click();
 | 
			
		||||
      cy.get('body').find('g#flowchart-Function-10').click();
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
 | 
			
		||||
    });
 | 
			
		||||
@@ -60,9 +57,7 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_loose.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('g[id="flowchart-1Function-14"]')
 | 
			
		||||
        .click();
 | 
			
		||||
      cy.get('body').find('g[id="flowchart-1Function-14"]').click();
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
 | 
			
		||||
    });
 | 
			
		||||
@@ -70,11 +65,9 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_loose.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('#flowchart-URL-11')
 | 
			
		||||
        .click();
 | 
			
		||||
      cy.get('body').find('#flowchart-URL-11').click();
 | 
			
		||||
 | 
			
		||||
      cy.location().should(location => {
 | 
			
		||||
      cy.location().should((location) => {
 | 
			
		||||
        expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -82,11 +75,9 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_loose.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('g[id="flowchart-2URL-15"]')
 | 
			
		||||
        .click();
 | 
			
		||||
      cy.get('body').find('g[id="flowchart-2URL-15"]').click();
 | 
			
		||||
 | 
			
		||||
      cy.location().should(location => {
 | 
			
		||||
      cy.location().should((location) => {
 | 
			
		||||
        expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -95,11 +86,9 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_loose.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('rect#cl1')
 | 
			
		||||
        .click({ force: true });
 | 
			
		||||
      cy.get('body').find('rect#cl1').click({ force: true });
 | 
			
		||||
 | 
			
		||||
      cy.location().should(location => {
 | 
			
		||||
      cy.location().should((location) => {
 | 
			
		||||
        expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -107,11 +96,9 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_loose.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('text#cl1-text')
 | 
			
		||||
        .click({ force: true });
 | 
			
		||||
      cy.get('body').find('text#cl1-text').click({ force: true });
 | 
			
		||||
 | 
			
		||||
      cy.location().should(location => {
 | 
			
		||||
      cy.location().should((location) => {
 | 
			
		||||
        expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -119,9 +106,7 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_loose.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('rect#cl2')
 | 
			
		||||
        .click({ force: true });
 | 
			
		||||
      cy.get('body').find('rect#cl2').click({ force: true });
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant cl2');
 | 
			
		||||
    });
 | 
			
		||||
@@ -129,9 +114,7 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_loose.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('rect#cl3')
 | 
			
		||||
        .click({ force: true });
 | 
			
		||||
      cy.get('body').find('rect#cl3').click({ force: true });
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant test1 test2 test3');
 | 
			
		||||
    });
 | 
			
		||||
@@ -140,9 +123,7 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_loose.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('text#cl2-text')
 | 
			
		||||
        .click({ force: true });
 | 
			
		||||
      cy.get('body').find('text#cl2-text').click({ force: true });
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant cl2');
 | 
			
		||||
    });
 | 
			
		||||
@@ -150,13 +131,10 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_loose.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('text#cl3-text')
 | 
			
		||||
        .click({ force: true });
 | 
			
		||||
      cy.get('body').find('text#cl3-text').click({ force: true });
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant test1 test2 test3');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('Interaction - security level tight', () => {
 | 
			
		||||
@@ -164,31 +142,27 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_strict.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('g#flowchart-Function-2')
 | 
			
		||||
        .click();
 | 
			
		||||
      cy.get('body').find('g#flowchart-Function-2').click();
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
 | 
			
		||||
      cy.get('.created-by-click').should('not.exist');
 | 
			
		||||
      // cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
 | 
			
		||||
    });
 | 
			
		||||
    it('should handle a click on a node with a bound function where the node starts with a number', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_strict.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('g[id="flowchart-1Function-6"]')
 | 
			
		||||
        .click();
 | 
			
		||||
      cy.get('body').find('g[id="flowchart-1Function-6"]').click();
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
 | 
			
		||||
      // cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
 | 
			
		||||
      cy.get('.created-by-click').should('not.exist');
 | 
			
		||||
    });
 | 
			
		||||
    it('should handle a click on a node with a bound url', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_strict.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('g#flowchart-URL-3')
 | 
			
		||||
        .click();
 | 
			
		||||
      cy.get('body').find('g#flowchart-URL-3').click();
 | 
			
		||||
 | 
			
		||||
      cy.location().should(location => {
 | 
			
		||||
      cy.location().should((location) => {
 | 
			
		||||
        expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -196,11 +170,9 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_strict.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('g[id="flowchart-2URL-7"]')
 | 
			
		||||
        .click();
 | 
			
		||||
      cy.get('body').find('g[id="flowchart-2URL-7"]').click();
 | 
			
		||||
 | 
			
		||||
      cy.location().should(location => {
 | 
			
		||||
      cy.location().should((location) => {
 | 
			
		||||
        expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -209,11 +181,9 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_strict.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('rect#cl1')
 | 
			
		||||
        .click({ force: true });
 | 
			
		||||
      cy.get('body').find('rect#cl1').click({ force: true });
 | 
			
		||||
 | 
			
		||||
      cy.location().should(location => {
 | 
			
		||||
      cy.location().should((location) => {
 | 
			
		||||
        expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -221,11 +191,9 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_strict.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('text#cl1-text')
 | 
			
		||||
        .click({ force: true });
 | 
			
		||||
      cy.get('body').find('text#cl1-text').click({ force: true });
 | 
			
		||||
 | 
			
		||||
      cy.location().should(location => {
 | 
			
		||||
      cy.location().should((location) => {
 | 
			
		||||
        expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -233,21 +201,19 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_strict.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('rect#cl2')
 | 
			
		||||
        .click({ force: true });
 | 
			
		||||
      cy.get('body').find('rect#cl2').click({ force: true });
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2');
 | 
			
		||||
      // cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2');
 | 
			
		||||
      cy.get('.created-by-gant-click').should('not.exist');
 | 
			
		||||
    });
 | 
			
		||||
    it('should handle a click on a task with a bound function', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_strict.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('text#cl2-text')
 | 
			
		||||
        .click({ force: true });
 | 
			
		||||
      cy.get('body').find('text#cl2-text').click({ force: true });
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2');
 | 
			
		||||
      // cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2');
 | 
			
		||||
      cy.get('.created-by-gant-click').should('not.exist');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -256,31 +222,27 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_other.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('g#flowchart-Function-2')
 | 
			
		||||
        .click();
 | 
			
		||||
      cy.get('body').find('g#flowchart-Function-2').click();
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
 | 
			
		||||
      // cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
 | 
			
		||||
      cy.get('.created-by-click').should('not.exist');
 | 
			
		||||
    });
 | 
			
		||||
    it('should handle a click on a node with a bound function where the node starts with a number', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_other.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('g[id="flowchart-1Function-6"]')
 | 
			
		||||
        .click();
 | 
			
		||||
      cy.get('body').find('g[id="flowchart-1Function-6"]').click();
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
 | 
			
		||||
      cy.get('.created-by-click').should('not.exist');
 | 
			
		||||
      cy.get('.created-by-click').should('not.exist');
 | 
			
		||||
    });
 | 
			
		||||
    it('should handle a click on a node with a bound url', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_other.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('g#flowchart-URL-3')
 | 
			
		||||
        .click();
 | 
			
		||||
      cy.get('body').find('g#flowchart-URL-3').click();
 | 
			
		||||
 | 
			
		||||
      cy.location().should(location => {
 | 
			
		||||
      cy.location().should((location) => {
 | 
			
		||||
        expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -289,21 +251,17 @@ describe('Interaction', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_other.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('rect#cl2')
 | 
			
		||||
        .click({ force: true });
 | 
			
		||||
      cy.get('body').find('rect#cl2').click({ force: true });
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2');
 | 
			
		||||
      cy.get('.created-by-gant-click').should('not.exist');
 | 
			
		||||
    });
 | 
			
		||||
    it('should handle a click on a task with a bound function', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/click_security_other.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('text#cl2-text')
 | 
			
		||||
        .click({ force: true });
 | 
			
		||||
      cy.get('body').find('text#cl2-text').click({ force: true });
 | 
			
		||||
 | 
			
		||||
      cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2');
 | 
			
		||||
      cy.get('.created-by-gant-click').should('not.exist');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,22 +1,19 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
describe('Rerendering', () => {
 | 
			
		||||
    it('should be able to render after an error has occured', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/render-after-error.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('#graphDiv').should('exist');
 | 
			
		||||
    });
 | 
			
		||||
  it('should be able to render after an error has occured', () => {
 | 
			
		||||
    const url = 'http://localhost:9000/render-after-error.html';
 | 
			
		||||
    cy.viewport(1440, 1024);
 | 
			
		||||
    cy.visit(url);
 | 
			
		||||
    cy.get('#graphDiv').should('exist');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
    it('should be able to render and rerender a graph via API', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/rerender.html';
 | 
			
		||||
      cy.viewport(1440, 1024);
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('#graph [id^=flowchart-A]').should('have.text', 'XMas');
 | 
			
		||||
  it('should be able to render and rerender a graph via API', () => {
 | 
			
		||||
    const url = 'http://localhost:9000/rerender.html';
 | 
			
		||||
    cy.viewport(1440, 1024);
 | 
			
		||||
    cy.visit(url);
 | 
			
		||||
    cy.get('#graph [id^=flowchart-A]').should('have.text', 'XMas');
 | 
			
		||||
 | 
			
		||||
      cy.get('body')
 | 
			
		||||
        .find('#rerender')
 | 
			
		||||
        .click({ force: true });
 | 
			
		||||
    cy.get('body').find('#rerender').click({ force: true });
 | 
			
		||||
 | 
			
		||||
      cy.get('#graph [id^=flowchart-A]').should('have.text', 'Saturday');
 | 
			
		||||
    });
 | 
			
		||||
    cy.get('#graph [id^=flowchart-A]').should('have.text', 'Saturday');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,21 +1,16 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
describe('Sequencediagram', () => {
 | 
			
		||||
  it('should render a simple sequence diagrams', () => {
 | 
			
		||||
    const url = 'http://localhost:9000/webpackUsage.html';
 | 
			
		||||
 | 
			
		||||
    cy.visit(url);
 | 
			
		||||
    cy.get('body')
 | 
			
		||||
      .find('svg')
 | 
			
		||||
      .should('have.length', 1);
 | 
			
		||||
    cy.get('body').find('svg').should('have.length', 1);
 | 
			
		||||
  });
 | 
			
		||||
  it('should handle html escapings properly', () => {
 | 
			
		||||
    const url = 'http://localhost:9000/webpackUsage.html?test-html-escaping=true';
 | 
			
		||||
 | 
			
		||||
    cy.visit(url);
 | 
			
		||||
    cy.get('body')
 | 
			
		||||
      .find('svg')
 | 
			
		||||
      .should('have.length', 1);
 | 
			
		||||
    cy.get('body').find('svg').should('have.length', 1);
 | 
			
		||||
 | 
			
		||||
    cy.get('.label > g > foreignobject > div').should('not.contain.text', '<b>');
 | 
			
		||||
    cy.get('g.label > foreignobject > div').should('not.contain.text', '<b>');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,35 +1,118 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { mermaidUrl } from '../../helpers/util.js';
 | 
			
		||||
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
describe('XSS', () => {
 | 
			
		||||
  it('should handle xss in tags', () => {
 | 
			
		||||
    const str = 'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In19';
 | 
			
		||||
    const str =
 | 
			
		||||
      'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In19';
 | 
			
		||||
 | 
			
		||||
    const url = mermaidUrl(str,{}, true);
 | 
			
		||||
    const url = mermaidUrl(str, {}, true);
 | 
			
		||||
 | 
			
		||||
    cy.visit(url);
 | 
			
		||||
    cy.wait(1000).then(()=>{
 | 
			
		||||
    cy.wait(1000).then(() => {
 | 
			
		||||
      cy.get('.mermaid').should('exist');
 | 
			
		||||
    });
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
    // cy.percySnapshot()
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  })
 | 
			
		||||
  it('should handle xss in tags in non-html mode', () => {
 | 
			
		||||
    const str = 'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX19';
 | 
			
		||||
  it('should not allow tags in the css', () => {
 | 
			
		||||
    const str =
 | 
			
		||||
      'eyJjb2RlIjoiJSV7aW5pdDogeyAnZm9udEZhbWlseSc6ICdcXFwiPjwvc3R5bGU-PGltZyBzcmM9eCBvbmVycm9yPXhzc0F0dGFjaygpPid9IH0lJVxuZ3JhcGggTFJcbiAgICAgQSAtLT4gQiIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9';
 | 
			
		||||
 | 
			
		||||
    const url = mermaidUrl(str,{
 | 
			
		||||
      "theme": "default",
 | 
			
		||||
      "flowchart": {
 | 
			
		||||
        "htmlMode": false
 | 
			
		||||
      }
 | 
			
		||||
    }, true);
 | 
			
		||||
    const url = mermaidUrl(
 | 
			
		||||
      str,
 | 
			
		||||
      {
 | 
			
		||||
        theme: 'default',
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          htmlMode: false,
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      true
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    cy.visit(url);
 | 
			
		||||
    // cy.get('svg')
 | 
			
		||||
    // cy.percySnapshot()
 | 
			
		||||
    cy.get('.malware').should('not.exist');
 | 
			
		||||
    cy.wait(1000).then(() => {
 | 
			
		||||
      cy.get('#the-malware').should('not.exist');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
  it('should handle xss in tags in non-html mode', () => {
 | 
			
		||||
    const str =
 | 
			
		||||
      'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX19';
 | 
			
		||||
 | 
			
		||||
    const url = mermaidUrl(
 | 
			
		||||
      str,
 | 
			
		||||
      {
 | 
			
		||||
        theme: 'default',
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          htmlMode: false,
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      true
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    cy.visit(url);
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should not allow changing the __proto__ attribute using config', () => {
 | 
			
		||||
    cy.visit('http://localhost:9000/xss2.html');
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
  it('should not allow maniplulating htmlLabels into a false positive', () => {
 | 
			
		||||
    cy.visit('http://localhost:9000/xss4.html');
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
  it('should not allow maniplulating antiscript to run javascript', () => {
 | 
			
		||||
    cy.visit('http://localhost:9000/xss5.html');
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
  it('should not allow maniplulating antiscript to run javascript using onerror', () => {
 | 
			
		||||
    cy.visit('http://localhost:9000/xss6.html');
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
  it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre wrapper', () => {
 | 
			
		||||
    cy.visit('http://localhost:9000/xss8.html');
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
  it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
 | 
			
		||||
    cy.visit('http://localhost:9000/xss9.html');
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
  it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
 | 
			
		||||
    cy.visit('http://localhost:9000/xss10.html');
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
  it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
 | 
			
		||||
    cy.visit('http://localhost:9000/xss11.html');
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
  it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
 | 
			
		||||
    cy.visit('http://localhost:9000/xss12.html');
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
  it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
 | 
			
		||||
    cy.visit('http://localhost:9000/xss13.html');
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
  it('should not allow maniplulating antiscript to run javascript iframes in class diagrams', () => {
 | 
			
		||||
    cy.visit('http://localhost:9000/xss14.html');
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
  it('should sanitize cardinalities properly in class diagrams', () => {
 | 
			
		||||
    cy.visit('http://localhost:9000/xss18.html');
 | 
			
		||||
    cy.wait(1000);
 | 
			
		||||
    cy.get('#the-malware').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,8 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { imgSnapshotTest } from '../../helpers/util';
 | 
			
		||||
describe('Class diagram V2', () => {
 | 
			
		||||
 | 
			
		||||
    it('0: should render a simple class diagram', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
  it('0: should render a simple class diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
        classDiagram-v2
 | 
			
		||||
 | 
			
		||||
        classA -- classB : Inheritance
 | 
			
		||||
@@ -13,10 +11,10 @@ describe('Class diagram V2', () => {
 | 
			
		||||
        classB -- classD
 | 
			
		||||
 | 
			
		||||
        `,
 | 
			
		||||
        {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
      );
 | 
			
		||||
      cy.get('svg');
 | 
			
		||||
    });
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('1: should render a simple class diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -47,7 +45,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -76,8 +74,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -95,7 +92,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
      Class01 : +int publicGorilla
 | 
			
		||||
      Class01 : #int protectedMarmoset
 | 
			
		||||
      `,
 | 
			
		||||
       {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -103,7 +100,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
  it('should render multiple class diagrams', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      [
 | 
			
		||||
      `
 | 
			
		||||
        `
 | 
			
		||||
    classDiagram-v2
 | 
			
		||||
      Class01 "1" <|--|> "*" AveryLongClass : Cool
 | 
			
		||||
      <<interface>> Class01
 | 
			
		||||
@@ -125,7 +122,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      `
 | 
			
		||||
        `
 | 
			
		||||
    classDiagram-v2
 | 
			
		||||
      Class01 "1" <|--|> "*" AveryLongClass : Cool
 | 
			
		||||
      <<interface>> Class01
 | 
			
		||||
@@ -148,7 +145,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      ],
 | 
			
		||||
       {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -178,7 +175,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
       {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -190,7 +187,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
      Class01 <|-- AveryLongClass : Cool
 | 
			
		||||
      Class01 : someMethod()*
 | 
			
		||||
      `,
 | 
			
		||||
       {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -202,7 +199,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
      Class01 <|-- AveryLongClass : Cool
 | 
			
		||||
      Class01 : someMethod()$
 | 
			
		||||
      `,
 | 
			
		||||
       {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -222,7 +219,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
       {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -243,7 +240,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
       {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -265,7 +262,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
      }
 | 
			
		||||
      link Class01 "google.com" "A Tooltip"
 | 
			
		||||
      `,
 | 
			
		||||
       {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -287,7 +284,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
      }
 | 
			
		||||
      callback Class01 "functionCall" "A Tooltip"
 | 
			
		||||
      `,
 | 
			
		||||
       {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -302,7 +299,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
        testArray() bool[]
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
       {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -318,7 +315,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
        testArray() bool[]
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
       {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -336,7 +333,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
 | 
			
		||||
      cssClass "Class10" exClass2
 | 
			
		||||
      `,
 | 
			
		||||
       {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -352,7 +349,7 @@ describe('Class diagram V2', () => {
 | 
			
		||||
        testArray() bool[]
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
       {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -366,7 +363,118 @@ describe('Class diagram V2', () => {
 | 
			
		||||
 | 
			
		||||
      cssClass "Class10, class20" exClass2
 | 
			
		||||
      `,
 | 
			
		||||
       {logLevel : 1, flowchart: { "htmlLabels": false },}
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('16a: should render a simple class diagram with static field', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram-v2
 | 
			
		||||
      class Foo {
 | 
			
		||||
        +String bar$
 | 
			
		||||
      }
 | 
			
		||||
            `,
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('16b: should handle the direction statemnent with TB', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      classDiagram
 | 
			
		||||
        direction TB
 | 
			
		||||
        class Student {
 | 
			
		||||
          -idCard : IdCard
 | 
			
		||||
        }
 | 
			
		||||
        class IdCard{
 | 
			
		||||
          -id : int
 | 
			
		||||
          -name : string
 | 
			
		||||
        }
 | 
			
		||||
        class Bike{
 | 
			
		||||
          -id : int
 | 
			
		||||
          -name : string
 | 
			
		||||
        }
 | 
			
		||||
        Student "1" --o "1" IdCard : carries
 | 
			
		||||
        Student "1" --o "1" Bike : rides
 | 
			
		||||
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('18: should handle the direction statemnent with LR', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      classDiagram
 | 
			
		||||
        direction LR
 | 
			
		||||
        class Student {
 | 
			
		||||
          -idCard : IdCard
 | 
			
		||||
        }
 | 
			
		||||
        class IdCard{
 | 
			
		||||
          -id : int
 | 
			
		||||
          -name : string
 | 
			
		||||
        }
 | 
			
		||||
        class Bike{
 | 
			
		||||
          -id : int
 | 
			
		||||
          -name : string
 | 
			
		||||
        }
 | 
			
		||||
        Student "1" --o "1" IdCard : carries
 | 
			
		||||
        Student "1" --o "1" Bike : rides
 | 
			
		||||
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('17a: should handle the direction statemnent with BT', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      classDiagram
 | 
			
		||||
        direction BT
 | 
			
		||||
        class Student {
 | 
			
		||||
          -idCard : IdCard
 | 
			
		||||
        }
 | 
			
		||||
        class IdCard{
 | 
			
		||||
          -id : int
 | 
			
		||||
          -name : string
 | 
			
		||||
        }
 | 
			
		||||
        class Bike{
 | 
			
		||||
          -id : int
 | 
			
		||||
          -name : string
 | 
			
		||||
        }
 | 
			
		||||
        Student "1" --o "1" IdCard : carries
 | 
			
		||||
        Student "1" --o "1" Bike : rides
 | 
			
		||||
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('17b: should handle the direction statemment with RL', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      classDiagram
 | 
			
		||||
        direction RL
 | 
			
		||||
        class Student {
 | 
			
		||||
          -idCard : IdCard
 | 
			
		||||
        }
 | 
			
		||||
        class IdCard{
 | 
			
		||||
          -id : int
 | 
			
		||||
          -name : string
 | 
			
		||||
        }
 | 
			
		||||
        class Bike{
 | 
			
		||||
          -id : int
 | 
			
		||||
          -name : string
 | 
			
		||||
        }
 | 
			
		||||
        Student "1" --o "1" IdCard : carries
 | 
			
		||||
        Student "1" --o "1" Bike : rides
 | 
			
		||||
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 1, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 
 | 
			
		||||
@@ -1,406 +1,410 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
 | 
			
		||||
 | 
			
		||||
describe('Class diagram', () => {
 | 
			
		||||
  it('1: should render a simple class diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      Class01 <|-- AveryLongClass : Cool
 | 
			
		||||
      <<interface>> Class01
 | 
			
		||||
      Class03 *-- Class04
 | 
			
		||||
      Class05 o-- Class06
 | 
			
		||||
      Class07 .. Class08
 | 
			
		||||
      Class09 --> C2 : Where am i?
 | 
			
		||||
      Class09 --* C3
 | 
			
		||||
      Class09 --|> Class07
 | 
			
		||||
      Class12 <|.. Class08
 | 
			
		||||
      Class11 ..>Class12
 | 
			
		||||
      Class07 : equals()
 | 
			
		||||
      Class07 : Object[] elementData
 | 
			
		||||
      Class01 : size()
 | 
			
		||||
      Class01 : int chimp
 | 
			
		||||
      Class01 : int gorilla
 | 
			
		||||
      Class01 : -int privateChimp
 | 
			
		||||
      Class01 : +int publicGorilla
 | 
			
		||||
      Class01 : #int protectedMarmoset
 | 
			
		||||
      Class08 <--> C2: Cool label
 | 
			
		||||
      class Class10 {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {logLevel : 1}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('2: should render a simple class diagrams with cardinality', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      Class01 "1" <|--|> "*" AveryLongClass : Cool
 | 
			
		||||
      <<interface>> Class01
 | 
			
		||||
      Class03 "1" *-- "*" Class04
 | 
			
		||||
      Class05 "1" o-- "many" Class06
 | 
			
		||||
      Class07 "1" .. "*" Class08
 | 
			
		||||
      Class09 "1" --> "*" C2 : Where am i?
 | 
			
		||||
      Class09 "*" --* "*" C3
 | 
			
		||||
      Class09 "1" --|> "1" Class07
 | 
			
		||||
      Class07  : equals()
 | 
			
		||||
      Class07  : Object[] elementData
 | 
			
		||||
      Class01  : size()
 | 
			
		||||
      Class01  : int chimp
 | 
			
		||||
      Class01  : int gorilla
 | 
			
		||||
      Class08 "1" <--> "*" C2: Cool label
 | 
			
		||||
      class Class10 {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('3: should render a simple class diagram with different visibilities', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      Class01 <|-- AveryLongClass : Cool
 | 
			
		||||
      <<interface>> Class01
 | 
			
		||||
      Class01 : -privateMethod()
 | 
			
		||||
      Class01 : +publicMethod()
 | 
			
		||||
      Class01 : #protectedMethod()
 | 
			
		||||
      Class01 : -int privateChimp
 | 
			
		||||
      Class01 : +int publicGorilla
 | 
			
		||||
      Class01 : #int protectedMarmoset
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('4: should render a simple class diagram with comments', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      %% this is a comment
 | 
			
		||||
      Class01 <|-- AveryLongClass : Cool
 | 
			
		||||
      <<interface>> Class01
 | 
			
		||||
      Class03 *-- Class04
 | 
			
		||||
      Class05 o-- Class06
 | 
			
		||||
      Class07 .. Class08
 | 
			
		||||
      Class09 --> C2 : Where am i?
 | 
			
		||||
      Class09 --* C3
 | 
			
		||||
      Class09 --|> Class07
 | 
			
		||||
      Class07 : equals()
 | 
			
		||||
      Class07 : Object[] elementData
 | 
			
		||||
      Class01 : size()
 | 
			
		||||
      Class01 : int chimp
 | 
			
		||||
      Class01 : int gorilla
 | 
			
		||||
      Class08 <--> C2: Cool label
 | 
			
		||||
      class Class10 {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('5: should render a simple class diagram with abstract method', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      Class01 <|-- AveryLongClass : Cool
 | 
			
		||||
      Class01 : someMethod()*
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('6: should render a simple class diagram with static method', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      Class01 <|-- AveryLongClass : Cool
 | 
			
		||||
      Class01 : someMethod()$
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('7: should render a simple class diagram with Generic class', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
    class Class01~T~
 | 
			
		||||
      Class01 : size()
 | 
			
		||||
      Class01 : int chimp
 | 
			
		||||
      Class01 : int gorilla
 | 
			
		||||
      Class08 <--> C2: Cool label
 | 
			
		||||
      class Class10~T~ {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('8: should render a simple class diagram with Generic class and relations', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
    Class01~T~ <|-- AveryLongClass : Cool
 | 
			
		||||
    Class03~T~ *-- Class04~T~
 | 
			
		||||
      Class01 : size()
 | 
			
		||||
      Class01 : int chimp
 | 
			
		||||
      Class01 : int gorilla
 | 
			
		||||
      Class08 <--> C2: Cool label
 | 
			
		||||
      class Class10~T~ {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('9: should render a simple class diagram with clickable link', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
    Class01~T~ <|-- AveryLongClass : Cool
 | 
			
		||||
    Class03~T~ *-- Class04~T~
 | 
			
		||||
      Class01 : size()
 | 
			
		||||
      Class01 : int chimp
 | 
			
		||||
      Class01 : int gorilla
 | 
			
		||||
      Class08 <--> C2: Cool label
 | 
			
		||||
      class Class10~T~ {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      link Class01 "google.com" "A Tooltip"
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('10: should render a simple class diagram with clickable callback', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
    Class01~T~ <|-- AveryLongClass : Cool
 | 
			
		||||
    Class03~T~ *-- Class04~T~
 | 
			
		||||
      Class01 : size()
 | 
			
		||||
      Class01 : int chimp
 | 
			
		||||
      Class01 : int gorilla
 | 
			
		||||
      Class08 <--> C2: Cool label
 | 
			
		||||
      class Class10~T~ {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      callback Class01 "functionCall" "A Tooltip"
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('11: should render a simple class diagram with return type on method', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      class Class10~T~ {
 | 
			
		||||
        int[] id
 | 
			
		||||
        test(int[] ids) bool
 | 
			
		||||
        testArray() bool[]
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('12: should render a simple class diagram with generic types', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      class Class10~T~ {
 | 
			
		||||
        int[] id
 | 
			
		||||
        List~int~ ids
 | 
			
		||||
        test(List~int~ ids) List~bool~
 | 
			
		||||
        testArray() bool[]
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('13: should render a simple class diagram with css classes applied', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      class Class10 {
 | 
			
		||||
        int[] id
 | 
			
		||||
        List~int~ ids
 | 
			
		||||
        test(List~int~ ids) List~bool~
 | 
			
		||||
        testArray() bool[]
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      cssClass "Class10" exClass
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('14: should render a simple class diagram with css classes applied directly', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      class Class10:::exClass {
 | 
			
		||||
        int[] id
 | 
			
		||||
        List~int~ ids
 | 
			
		||||
        test(List~int~ ids) List~bool~
 | 
			
		||||
        testArray() bool[]
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('15: should render a simple class diagram with css classes applied two multiple classes', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      class Class10
 | 
			
		||||
      class Class20
 | 
			
		||||
 | 
			
		||||
      cssClass "Class10, class20" exClass
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('16: should render multiple class diagrams', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      [
 | 
			
		||||
        `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      Class01 "1" <|--|> "*" AveryLongClass : Cool
 | 
			
		||||
      <<interface>> Class01
 | 
			
		||||
      Class03 "1" *-- "*" Class04
 | 
			
		||||
      Class05 "1" o-- "many" Class06
 | 
			
		||||
      Class07 "1" .. "*" Class08
 | 
			
		||||
      Class09 "1" --> "*" C2 : Where am i?
 | 
			
		||||
      Class09 "*" --* "*" C3
 | 
			
		||||
      Class09 "1" --|> "1" Class07
 | 
			
		||||
      Class07  : equals()
 | 
			
		||||
      Class07  : Object[] elementData
 | 
			
		||||
      Class01  : size()
 | 
			
		||||
      Class01  : int chimp
 | 
			
		||||
      Class01  : int gorilla
 | 
			
		||||
      Class08 "1" <--> "*" C2: Cool label
 | 
			
		||||
      class Class10 {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
        `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      Class01 "1" <|--|> "*" AveryLongClass : Cool
 | 
			
		||||
      <<interface>> Class01
 | 
			
		||||
      Class03 "1" *-- "*" Class04
 | 
			
		||||
      Class05 "1" o-- "many" Class06
 | 
			
		||||
      Class07 "1" .. "*" Class08
 | 
			
		||||
      Class09 "1" --> "*" C2 : Where am i?
 | 
			
		||||
      Class09 "*" --* "*" C3
 | 
			
		||||
      Class09 "1" --|> "1" Class07
 | 
			
		||||
      Class07  : equals()
 | 
			
		||||
      Class07  : Object[] elementData
 | 
			
		||||
      Class01  : size()
 | 
			
		||||
      Class01  : int chimp
 | 
			
		||||
      Class01  : int gorilla
 | 
			
		||||
      Class08 "1" <--> "*" C2: Cool label
 | 
			
		||||
      class Class10 {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      ],
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('17: should render a class diagram when useMaxWidth is true (default)', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      Class01 <|-- AveryLongClass : Cool
 | 
			
		||||
      Class01 : size()
 | 
			
		||||
      Class01 : int chimp
 | 
			
		||||
      Class01 : int gorilla
 | 
			
		||||
      Class01 : -int privateChimp
 | 
			
		||||
      Class01 : +int publicGorilla
 | 
			
		||||
      Class01 : #int protectedMarmoset
 | 
			
		||||
      `,
 | 
			
		||||
      { class: { useMaxWidth: true } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
        expect(svg).to.have.attr('height', '218');
 | 
			
		||||
        const style = svg.attr('style');
 | 
			
		||||
        expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
        const maxWidthValue = parseInt(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
        // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
        expect(maxWidthValue).to.be.within(160 * .95, 160 * 1.05);
 | 
			
		||||
      });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('18: should render a class diagram when useMaxWidth is false', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      Class01 <|-- AveryLongClass : Cool
 | 
			
		||||
      Class01 : size()
 | 
			
		||||
      Class01 : int chimp
 | 
			
		||||
      Class01 : int gorilla
 | 
			
		||||
      Class01 : -int privateChimp
 | 
			
		||||
      Class01 : +int publicGorilla
 | 
			
		||||
      Class01 : #int protectedMarmoset
 | 
			
		||||
      `,
 | 
			
		||||
      { class: { useMaxWidth: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        const width = parseFloat(svg.attr('width'));
 | 
			
		||||
        // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
        expect(width).to.be.within(160 * .95, 160 * 1.05);
 | 
			
		||||
        expect(svg).to.have.attr('height', '218');
 | 
			
		||||
        expect(svg).to.not.have.attr('style');
 | 
			
		||||
      });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
 | 
			
		||||
 | 
			
		||||
describe('Class diagram', () => {
 | 
			
		||||
  it('1: should render a simple class diagram', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      Class01 <|-- AveryLongClass : Cool
 | 
			
		||||
      <<interface>> Class01
 | 
			
		||||
      Class03 *-- Class04
 | 
			
		||||
      Class05 o-- Class06
 | 
			
		||||
      Class07 .. Class08
 | 
			
		||||
      Class09 --> C2 : Where am i?
 | 
			
		||||
      Class09 --* C3
 | 
			
		||||
      Class09 --|> Class07
 | 
			
		||||
      Class12 <|.. Class08
 | 
			
		||||
      Class11 ..>Class12
 | 
			
		||||
      Class07 : equals()
 | 
			
		||||
      Class07 : Object[] elementData
 | 
			
		||||
      Class01 : size()
 | 
			
		||||
      Class01 : int chimp
 | 
			
		||||
      Class01 : int gorilla
 | 
			
		||||
      Class01 : -int privateChimp
 | 
			
		||||
      Class01 : +int publicGorilla
 | 
			
		||||
      Class01 : #int protectedMarmoset
 | 
			
		||||
      Class08 <--> C2: Cool label
 | 
			
		||||
      class Class10 {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('2: should render a simple class diagrams with cardinality', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      Class01 "1" <|--|> "*" AveryLongClass : Cool
 | 
			
		||||
      <<interface>> Class01
 | 
			
		||||
      Class03 "1" *-- "*" Class04
 | 
			
		||||
      Class05 "1" o-- "many" Class06
 | 
			
		||||
      Class07 "1" .. "*" Class08
 | 
			
		||||
      Class09 "1" --> "*" C2 : Where am i?
 | 
			
		||||
      Class09 "*" --* "*" C3
 | 
			
		||||
      Class09 "1" --|> "1" Class07
 | 
			
		||||
      Class07  : equals()
 | 
			
		||||
      Class07  : Object[] elementData
 | 
			
		||||
      Class01  : size()
 | 
			
		||||
      Class01  : int chimp
 | 
			
		||||
      Class01  : int gorilla
 | 
			
		||||
      Class08 "1" <--> "*" C2: Cool label
 | 
			
		||||
      class Class10 {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('3: should render a simple class diagram with different visibilities', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      Class01 <|-- AveryLongClass : Cool
 | 
			
		||||
      <<interface>> Class01
 | 
			
		||||
      Class01 : -privateMethod()
 | 
			
		||||
      Class01 : +publicMethod()
 | 
			
		||||
      Class01 : #protectedMethod()
 | 
			
		||||
      Class01 : -int privateChimp
 | 
			
		||||
      Class01 : +int publicGorilla
 | 
			
		||||
      Class01 : #int protectedMarmoset
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('4: should render a simple class diagram with comments', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      %% this is a comment
 | 
			
		||||
      Class01 <|-- AveryLongClass : Cool
 | 
			
		||||
      <<interface>> Class01
 | 
			
		||||
      Class03 *-- Class04
 | 
			
		||||
      Class05 o-- Class06
 | 
			
		||||
      Class07 .. Class08
 | 
			
		||||
      Class09 --> C2 : Where am i?
 | 
			
		||||
      Class09 --* C3
 | 
			
		||||
      Class09 --|> Class07
 | 
			
		||||
      Class07 : equals()
 | 
			
		||||
      Class07 : Object[] elementData
 | 
			
		||||
      Class01 : size()
 | 
			
		||||
      Class01 : int chimp
 | 
			
		||||
      Class01 : int gorilla
 | 
			
		||||
      Class08 <--> C2: Cool label
 | 
			
		||||
      class Class10 {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('5: should render a simple class diagram with abstract method', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      Class01 <|-- AveryLongClass : Cool
 | 
			
		||||
      Class01 : someMethod()*
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('6: should render a simple class diagram with static method', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      Class01 <|-- AveryLongClass : Cool
 | 
			
		||||
      Class01 : someMethod()$
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('7: should render a simple class diagram with Generic class', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
    class Class01~T~
 | 
			
		||||
      Class01 : size()
 | 
			
		||||
      Class01 : int chimp
 | 
			
		||||
      Class01 : int gorilla
 | 
			
		||||
      Class08 <--> C2: Cool label
 | 
			
		||||
      class Class10~T~ {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('8: should render a simple class diagram with Generic class and relations', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
    Class01~T~ <|-- AveryLongClass : Cool
 | 
			
		||||
    Class03~T~ *-- Class04~T~
 | 
			
		||||
      Class01 : size()
 | 
			
		||||
      Class01 : int chimp
 | 
			
		||||
      Class01 : int gorilla
 | 
			
		||||
      Class08 <--> C2: Cool label
 | 
			
		||||
      class Class10~T~ {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('9: should render a simple class diagram with clickable link', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
    Class01~T~ <|-- AveryLongClass : Cool
 | 
			
		||||
    Class03~T~ *-- Class04~T~
 | 
			
		||||
      Class01 : size()
 | 
			
		||||
      Class01 : int chimp
 | 
			
		||||
      Class01 : int gorilla
 | 
			
		||||
      Class08 <--> C2: Cool label
 | 
			
		||||
      class Class10~T~ {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      link Class01 "google.com" "A Tooltip"
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('10: should render a simple class diagram with clickable callback', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
    Class01~T~ <|-- AveryLongClass : Cool
 | 
			
		||||
    Class03~T~ *-- Class04~T~
 | 
			
		||||
      Class01 : size()
 | 
			
		||||
      Class01 : int chimp
 | 
			
		||||
      Class01 : int gorilla
 | 
			
		||||
      Class08 <--> C2: Cool label
 | 
			
		||||
      class Class10~T~ {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      callback Class01 "functionCall" "A Tooltip"
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('11: should render a simple class diagram with return type on method', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      class Class10~T~ {
 | 
			
		||||
        int[] id
 | 
			
		||||
        test(int[] ids) bool
 | 
			
		||||
        testArray() bool[]
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('12: should render a simple class diagram with generic types', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      class Class10~T~ {
 | 
			
		||||
        int[] id
 | 
			
		||||
        List~int~ ids
 | 
			
		||||
        test(List~int~ ids) List~bool~
 | 
			
		||||
        testArray() bool[]
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('13: should render a simple class diagram with css classes applied', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      class Class10 {
 | 
			
		||||
        int[] id
 | 
			
		||||
        List~int~ ids
 | 
			
		||||
        test(List~int~ ids) List~bool~
 | 
			
		||||
        testArray() bool[]
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      class Class10:::exClass2
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('14: should render a simple class diagram with css classes applied directly', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      class Class10:::exClass2 {
 | 
			
		||||
        int[] id
 | 
			
		||||
        List~int~ ids
 | 
			
		||||
        test(List~int~ ids) List~bool~
 | 
			
		||||
        testArray() bool[]
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('15: should render a simple class diagram with css classes applied two multiple classes', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      class Class10
 | 
			
		||||
      class Class20
 | 
			
		||||
 | 
			
		||||
      cssClass "Class10, Class20" exClass2
 | 
			
		||||
      class Class20:::exClass2
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('16: should render multiple class diagrams', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      [
 | 
			
		||||
        `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      Class01 "1" <|--|> "*" AveryLongClass : Cool
 | 
			
		||||
      <<interface>> Class01
 | 
			
		||||
      Class03 "1" *-- "*" Class04
 | 
			
		||||
      Class05 "1" o-- "many" Class06
 | 
			
		||||
      Class07 "1" .. "*" Class08
 | 
			
		||||
      Class09 "1" --> "*" C2 : Where am i?
 | 
			
		||||
      Class09 "*" --* "*" C3
 | 
			
		||||
      Class09 "1" --|> "1" Class07
 | 
			
		||||
      Class07  : equals()
 | 
			
		||||
      Class07  : Object[] elementData
 | 
			
		||||
      Class01  : size()
 | 
			
		||||
      Class01  : int chimp
 | 
			
		||||
      Class01  : int gorilla
 | 
			
		||||
      Class08 "1" <--> "*" C2: Cool label
 | 
			
		||||
      class Class10 {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
        `
 | 
			
		||||
    classDiagram
 | 
			
		||||
      Class01 "1" <|--|> "*" AveryLongClass : Cool
 | 
			
		||||
      <<interface>> Class01
 | 
			
		||||
      Class03 "1" *-- "*" Class04
 | 
			
		||||
      Class05 "1" o-- "many" Class06
 | 
			
		||||
      Class07 "1" .. "*" Class08
 | 
			
		||||
      Class09 "1" --> "*" C2 : Where am i?
 | 
			
		||||
      Class09 "*" --* "*" C3
 | 
			
		||||
      Class09 "1" --|> "1" Class07
 | 
			
		||||
      Class07  : equals()
 | 
			
		||||
      Class07  : Object[] elementData
 | 
			
		||||
      Class01  : size()
 | 
			
		||||
      Class01  : int chimp
 | 
			
		||||
      Class01  : int gorilla
 | 
			
		||||
      Class08 "1" <--> "*" C2: Cool label
 | 
			
		||||
      class Class10 {
 | 
			
		||||
        <<service>>
 | 
			
		||||
        int id
 | 
			
		||||
        test()
 | 
			
		||||
      }
 | 
			
		||||
      `,
 | 
			
		||||
      ],
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // it('17: should render a class diagram when useMaxWidth is true (default)', () => {
 | 
			
		||||
  //   renderGraph(
 | 
			
		||||
  //     `
 | 
			
		||||
  //   classDiagram
 | 
			
		||||
  //     Class01 <|-- AveryLongClass : Cool
 | 
			
		||||
  //     Class01 : size()
 | 
			
		||||
  //     Class01 : int chimp
 | 
			
		||||
  //     Class01 : int gorilla
 | 
			
		||||
  //     Class01 : -int privateChimp
 | 
			
		||||
  //     Class01 : +int publicGorilla
 | 
			
		||||
  //     Class01 : #int protectedMarmoset
 | 
			
		||||
  //     `,
 | 
			
		||||
  //     { class: { useMaxWidth: true } }
 | 
			
		||||
  //   );
 | 
			
		||||
  //   cy.get('svg')
 | 
			
		||||
  //     .should((svg) => {
 | 
			
		||||
  //       expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
  //       const height = parseFloat(svg.attr('height'));
 | 
			
		||||
  //       expect(height).to.be.within(332, 333);
 | 
			
		||||
  //      // expect(svg).to.have.attr('height', '218');
 | 
			
		||||
  //       const style = svg.attr('style');
 | 
			
		||||
  //       expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
  //       const maxWidthValue = parseInt(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
  //       // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
  //       expect(maxWidthValue).to.be.within(203, 204);
 | 
			
		||||
  //     });
 | 
			
		||||
  // });
 | 
			
		||||
 | 
			
		||||
  // it('18: should render a class diagram when useMaxWidth is false', () => {
 | 
			
		||||
  //   renderGraph(
 | 
			
		||||
  //     `
 | 
			
		||||
  //   classDiagram
 | 
			
		||||
  //     Class01 <|-- AveryLongClass : Cool
 | 
			
		||||
  //     Class01 : size()
 | 
			
		||||
  //     Class01 : int chimp
 | 
			
		||||
  //     Class01 : int gorilla
 | 
			
		||||
  //     Class01 : -int privateChimp
 | 
			
		||||
  //     Class01 : +int publicGorilla
 | 
			
		||||
  //     Class01 : #int protectedMarmoset
 | 
			
		||||
  //     `,
 | 
			
		||||
  //     { class: { useMaxWidth: false } }
 | 
			
		||||
  //   );
 | 
			
		||||
  //   cy.get('svg')
 | 
			
		||||
  //     .should((svg) => {
 | 
			
		||||
  //       const width = parseFloat(svg.attr('width'));
 | 
			
		||||
  //       // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
  //       expect(width).to.be.within(100, 101);
 | 
			
		||||
  //       const height = parseFloat(svg.attr('height'));
 | 
			
		||||
  //       expect(height).to.be.within(332, 333);
 | 
			
		||||
  //      // expect(svg).to.have.attr('height', '332');
 | 
			
		||||
  //      // expect(svg).to.not.have.attr('style');
 | 
			
		||||
  //     });
 | 
			
		||||
  // });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,9 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { imgSnapshotTest } from '../../helpers/util.js';
 | 
			
		||||
 | 
			
		||||
describe('Configuration and directives - nodes should be light blue', () => {
 | 
			
		||||
    it('No config - use default', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
  it('No config - use default', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      graph TD
 | 
			
		||||
          A(Default) --> B[/Another/]
 | 
			
		||||
          A --> C[End]
 | 
			
		||||
@@ -13,13 +12,13 @@ describe('Configuration and directives - nodes should be light blue', () => {
 | 
			
		||||
            C
 | 
			
		||||
          end
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
      cy.get('svg');
 | 
			
		||||
    });
 | 
			
		||||
    it('Settigns from intitialize - nodes should be green', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Settigns from intitialize - nodes should be green', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
graph TD
 | 
			
		||||
          A(Forest) --> B[/Another/]
 | 
			
		||||
          A --> C[End]
 | 
			
		||||
@@ -27,13 +26,13 @@ graph TD
 | 
			
		||||
            B
 | 
			
		||||
            C
 | 
			
		||||
          end          `,
 | 
			
		||||
        {theme:'forest'}
 | 
			
		||||
      );
 | 
			
		||||
      cy.get('svg');
 | 
			
		||||
    });
 | 
			
		||||
    it('Settings from initialize overriding themeVariable - nodes shold be red', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      { theme: 'forest' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Settings from initialize overriding themeVariable - nodes shold be red', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        %%{init: { 'theme': 'base', 'themeVariables':{ 'primaryColor': '#ff0000'}}}%%
 | 
			
		||||
@@ -45,13 +44,13 @@ graph TD
 | 
			
		||||
            C
 | 
			
		||||
          end
 | 
			
		||||
        `,
 | 
			
		||||
        {theme:'base', themeVariables:{ primaryColor: '#ff0000'}, logLevel: 0}
 | 
			
		||||
      );
 | 
			
		||||
      cy.get('svg');
 | 
			
		||||
    });
 | 
			
		||||
    it('Settings from directive - nodes should be grey', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      { theme: 'base', themeVariables: { primaryColor: '#ff0000' }, logLevel: 0 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Settings from directive - nodes should be grey', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
        %%{init: { 'logLevel': 0, 'theme': 'neutral'} }%%
 | 
			
		||||
graph TD
 | 
			
		||||
          A(Start) --> B[/Another/]
 | 
			
		||||
@@ -61,14 +60,14 @@ graph TD
 | 
			
		||||
            C
 | 
			
		||||
          end
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
      cy.get('svg');
 | 
			
		||||
    });
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
    it('Settings from directive overriding theme variable - nodes should be red', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
  it('Settings from directive overriding theme variable - nodes should be red', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
          %%{init: {'theme': 'base', 'themeVariables':{ 'primaryColor': '#ff0000'}}}%%
 | 
			
		||||
graph TD
 | 
			
		||||
          A(Start) --> B[/Another/]
 | 
			
		||||
@@ -78,13 +77,13 @@ graph TD
 | 
			
		||||
            C
 | 
			
		||||
          end
 | 
			
		||||
        `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
      cy.get('svg');
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
    it('Settings from initialize and directive - nodes should be grey', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
  it('Settings from initialize and directive - nodes should be grey', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      %%{init: { 'logLevel': 0, 'theme': 'neutral'} }%%
 | 
			
		||||
graph TD
 | 
			
		||||
          A(Start) --> B[/Another/]
 | 
			
		||||
@@ -94,13 +93,13 @@ graph TD
 | 
			
		||||
            C
 | 
			
		||||
          end
 | 
			
		||||
        `,
 | 
			
		||||
        {theme:'forest'}
 | 
			
		||||
      );
 | 
			
		||||
      cy.get('svg');
 | 
			
		||||
    });
 | 
			
		||||
    it('Theme from initialize, directive overriding theme variable - nodes should be red', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      { theme: 'forest' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Theme from initialize, directive overriding theme variable - nodes should be red', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      %%{init: {'theme': 'base', 'themeVariables':{ 'primaryColor': '#ff0000'}}}%%
 | 
			
		||||
graph TD
 | 
			
		||||
          A(Start) --> B[/Another/]
 | 
			
		||||
@@ -110,13 +109,13 @@ graph TD
 | 
			
		||||
            C
 | 
			
		||||
          end
 | 
			
		||||
        `,
 | 
			
		||||
        {theme:'base'}
 | 
			
		||||
      );
 | 
			
		||||
      cy.get('svg');
 | 
			
		||||
    });
 | 
			
		||||
    it('Theme variable from initialize, theme from directive - nodes should be red', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
      { theme: 'base' }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('Theme variable from initialize, theme from directive - nodes should be red', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      %%{init: { 'logLevel': 0, 'theme': 'base'} }%%
 | 
			
		||||
graph TD
 | 
			
		||||
          A(Start) --> B[/Another/]
 | 
			
		||||
@@ -126,16 +125,16 @@ graph TD
 | 
			
		||||
            C
 | 
			
		||||
          end
 | 
			
		||||
        `,
 | 
			
		||||
        {themeVariables:{primaryColor: '#ff0000'}}
 | 
			
		||||
      );
 | 
			
		||||
      { themeVariables: { primaryColor: '#ff0000' } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  describe('when rendering several diagrams', () => {
 | 
			
		||||
    it('diagrams should not taint later diagrams', () => {
 | 
			
		||||
      const url = 'http://localhost:9000/theme-directives.html';
 | 
			
		||||
      cy.visit(url);
 | 
			
		||||
      cy.get('svg');
 | 
			
		||||
    });
 | 
			
		||||
    describe('when rendering several diagrams', () => {
 | 
			
		||||
      it('diagrams should not taint later diagrams', () => {
 | 
			
		||||
        const url = 'http://localhost:9000/theme-directives.html';
 | 
			
		||||
        cy.visit(url);
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
        cy.percySnapshot();
 | 
			
		||||
      });
 | 
			
		||||
      cy.percySnapshot();
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { imgSnapshotTest } from '../../helpers/util';
 | 
			
		||||
 | 
			
		||||
describe('State diagram', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,12 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { imgSnapshotTest } from '../../helpers/util';
 | 
			
		||||
 | 
			
		||||
describe('Flowchart', () => {
 | 
			
		||||
 | 
			
		||||
  it('34: testing the label width in percy', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `graph TD
 | 
			
		||||
      A[Christmas]
 | 
			
		||||
      `,
 | 
			
		||||
      { theme: 'forest' , fontFamily: '"Noto Sans SC", sans-serif' }
 | 
			
		||||
      { theme: 'forest', fontFamily: '"Noto Sans SC", sans-serif' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
 | 
			
		||||
 | 
			
		||||
describe('Entity Relationship Diagram', () => {
 | 
			
		||||
@@ -9,7 +8,7 @@ describe('Entity Relationship Diagram', () => {
 | 
			
		||||
        CUSTOMER ||--o{ ORDER : places
 | 
			
		||||
        ORDER ||--|{ LINE-ITEM : contains
 | 
			
		||||
      `,
 | 
			
		||||
      {logLevel : 1}
 | 
			
		||||
      { logLevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -22,7 +21,7 @@ describe('Entity Relationship Diagram', () => {
 | 
			
		||||
        CUSTOMER ||--o{ ORDER : places
 | 
			
		||||
        ORDER ||--|{ LINE-ITEM : contains
 | 
			
		||||
      `,
 | 
			
		||||
      {logLevel : 1}
 | 
			
		||||
      { logLevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -34,7 +33,7 @@ describe('Entity Relationship Diagram', () => {
 | 
			
		||||
        CUSTOMER ||--|{ ADDRESS : "invoiced at"
 | 
			
		||||
        CUSTOMER ||--|{ ADDRESS : "receives goods at"
 | 
			
		||||
      `,
 | 
			
		||||
      {logLevel : 1}
 | 
			
		||||
      { logLevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -47,7 +46,7 @@ describe('Entity Relationship Diagram', () => {
 | 
			
		||||
        B ||--|{ C : likes
 | 
			
		||||
        C ||--|{ A : likes
 | 
			
		||||
      `,
 | 
			
		||||
      {logLevel : 1}
 | 
			
		||||
      { logLevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -65,7 +64,7 @@ describe('Entity Relationship Diagram', () => {
 | 
			
		||||
        PRODUCT-CATEGORY ||--|{ PRODUCT : contains
 | 
			
		||||
        PRODUCT ||--o{ ORDER-ITEM : "ordered in"
 | 
			
		||||
      `,
 | 
			
		||||
      {logLevel : 1}
 | 
			
		||||
      { logLevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -73,18 +72,18 @@ describe('Entity Relationship Diagram', () => {
 | 
			
		||||
  it('should render multiple ER diagrams', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      [
 | 
			
		||||
      `
 | 
			
		||||
        `
 | 
			
		||||
    erDiagram
 | 
			
		||||
        CUSTOMER ||--o{ ORDER : places
 | 
			
		||||
        ORDER ||--|{ LINE-ITEM : contains
 | 
			
		||||
      `,
 | 
			
		||||
      `
 | 
			
		||||
        `
 | 
			
		||||
    erDiagram
 | 
			
		||||
        CUSTOMER ||--o{ ORDER : places
 | 
			
		||||
        ORDER ||--|{ LINE-ITEM : contains
 | 
			
		||||
      `
 | 
			
		||||
      `,
 | 
			
		||||
      ],
 | 
			
		||||
      {logLevel : 1}
 | 
			
		||||
      { logLevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -97,7 +96,7 @@ describe('Entity Relationship Diagram', () => {
 | 
			
		||||
        BOOK }|..|{ GENRE : " "
 | 
			
		||||
        AUTHOR }|..|{ GENRE : "  "
 | 
			
		||||
      `,
 | 
			
		||||
      {logLevel : 1}
 | 
			
		||||
      { logLevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
@@ -111,16 +110,15 @@ describe('Entity Relationship Diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { er: { useMaxWidth: true } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
        expect(svg).to.have.attr('height', '465');
 | 
			
		||||
        const style = svg.attr('style');
 | 
			
		||||
        expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
        const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
        // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
        expect(maxWidthValue).to.be.within(140 * .95, 140 * 1.05);
 | 
			
		||||
      });
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
      expect(svg).to.have.attr('height', '465');
 | 
			
		||||
      const style = svg.attr('style');
 | 
			
		||||
      expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
      const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
      expect(maxWidthValue).to.be.within(140 * 0.95, 140 * 1.05);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render an ER when useMaxWidth is false', () => {
 | 
			
		||||
@@ -132,13 +130,114 @@ describe('Entity Relationship Diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { er: { useMaxWidth: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        const width = parseFloat(svg.attr('width'));
 | 
			
		||||
        // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
        expect(width).to.be.within(140 * .95, 140 * 1.05);
 | 
			
		||||
        expect(svg).to.have.attr('height', '465');
 | 
			
		||||
        expect(svg).to.not.have.attr('style');
 | 
			
		||||
      });
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      const width = parseFloat(svg.attr('width'));
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
      expect(width).to.be.within(140 * 0.95, 140 * 1.05);
 | 
			
		||||
      expect(svg).to.have.attr('height', '465');
 | 
			
		||||
      expect(svg).to.not.have.attr('style');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render entities that have no relationships', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `
 | 
			
		||||
    erDiagram
 | 
			
		||||
        DEAD_PARROT
 | 
			
		||||
        HERMIT
 | 
			
		||||
        RECLUSE
 | 
			
		||||
        SOCIALITE }o--o{ SOCIALITE : "interacts with"
 | 
			
		||||
        RECLUSE }o--o{ SOCIALITE : avoids
 | 
			
		||||
      `,
 | 
			
		||||
      { er: { useMaxWidth: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render entities with and without attributes', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `
 | 
			
		||||
    erDiagram
 | 
			
		||||
        BOOK { string title }
 | 
			
		||||
        AUTHOR }|..|{ BOOK : writes
 | 
			
		||||
        BOOK { float price }
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render entities and attributes with big and small entity names', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `
 | 
			
		||||
    erDiagram
 | 
			
		||||
        PRIVATE_FINANCIAL_INSTITUTION { 
 | 
			
		||||
          string name
 | 
			
		||||
          int    turnover
 | 
			
		||||
        }
 | 
			
		||||
        PRIVATE_FINANCIAL_INSTITUTION ||..|{ EMPLOYEE : employs
 | 
			
		||||
        EMPLOYEE { bool officer_of_firm }
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render entities with keys', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `
 | 
			
		||||
    erDiagram
 | 
			
		||||
      AUTHOR_WITH_LONG_ENTITY_NAME {
 | 
			
		||||
        string name PK
 | 
			
		||||
      }
 | 
			
		||||
      AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
 | 
			
		||||
      BOOK { 
 | 
			
		||||
          float price
 | 
			
		||||
          string author FK 
 | 
			
		||||
          string title PK
 | 
			
		||||
        }
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render entities with comments', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `
 | 
			
		||||
    erDiagram
 | 
			
		||||
      AUTHOR_WITH_LONG_ENTITY_NAME {
 | 
			
		||||
        string name "comment"
 | 
			
		||||
      }
 | 
			
		||||
      AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
 | 
			
		||||
      BOOK { 
 | 
			
		||||
          string author 
 | 
			
		||||
          string title "author comment"
 | 
			
		||||
          float price "price comment"
 | 
			
		||||
        }
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render entities with keys and comments', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `
 | 
			
		||||
    erDiagram
 | 
			
		||||
      AUTHOR_WITH_LONG_ENTITY_NAME {
 | 
			
		||||
        string name PK "comment"
 | 
			
		||||
      }
 | 
			
		||||
      AUTHOR_WITH_LONG_ENTITY_NAME }|..|{ BOOK : writes
 | 
			
		||||
      BOOK { 
 | 
			
		||||
          string description
 | 
			
		||||
          float price "price comment"
 | 
			
		||||
          string title PK "title comment"
 | 
			
		||||
          string author FK 
 | 
			
		||||
        }
 | 
			
		||||
      `,
 | 
			
		||||
      { logLevel: 1 }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
 | 
			
		||||
 | 
			
		||||
describe('Flowchart v2', () => {
 | 
			
		||||
@@ -29,7 +28,7 @@ describe('Flowchart v2', () => {
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
    it('3: a link with correct arrowhead to a subgraph', () => {
 | 
			
		||||
  it('3: a link with correct arrowhead to a subgraph', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `flowchart TD
 | 
			
		||||
        P1
 | 
			
		||||
@@ -69,7 +68,7 @@ describe('Flowchart v2', () => {
 | 
			
		||||
      `flowchart TD
 | 
			
		||||
        a["<strong>Haiya</strong>"]---->b
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: false, flowchart: {htmlLabels: false}}
 | 
			
		||||
      { htmlLabels: false, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('6: should render non-escaped with html labels', () => {
 | 
			
		||||
@@ -77,7 +76,7 @@ describe('Flowchart v2', () => {
 | 
			
		||||
      `flowchart TD
 | 
			
		||||
        a["<strong>Haiya</strong>"]===>b
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('7: should render a flowchart when useMaxWidth is true (default)', () => {
 | 
			
		||||
@@ -91,18 +90,17 @@ describe('Flowchart v2', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { useMaxWidth: true } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
        expect(svg).to.have.attr('height');
 | 
			
		||||
        // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
        const height = parseFloat(svg.attr('height'));
 | 
			
		||||
        expect(height).to.be.within(446 * .95, 446 * 1.05);
 | 
			
		||||
        const style = svg.attr('style');
 | 
			
		||||
        expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
        const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
        expect(maxWidthValue).to.be.within(300 * .95-1, 300 * 1.05);
 | 
			
		||||
      });
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
      expect(svg).to.have.attr('height');
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
      const height = parseFloat(svg.attr('height'));
 | 
			
		||||
      expect(height).to.be.within(446 * 0.95, 446 * 1.05);
 | 
			
		||||
      const style = svg.attr('style');
 | 
			
		||||
      expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
      const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
      expect(maxWidthValue).to.be.within(290 * 0.95 - 1, 290 * 1.05);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  it('8: should render a flowchart when useMaxWidth is false', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
@@ -115,15 +113,14 @@ describe('Flowchart v2', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { useMaxWidth: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        const height = parseFloat(svg.attr('height'));
 | 
			
		||||
        const width = parseFloat(svg.attr('width'));
 | 
			
		||||
        // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
        expect(height).to.be.within(446 * .95, 446 * 1.05);
 | 
			
		||||
        expect(width).to.be.within(300 * .95-1, 300 * 1.05);
 | 
			
		||||
        expect(svg).to.not.have.attr('style');
 | 
			
		||||
      });
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      const height = parseFloat(svg.attr('height'));
 | 
			
		||||
      const width = parseFloat(svg.attr('width'));
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
      expect(height).to.be.within(446 * 0.95, 446 * 1.05);
 | 
			
		||||
      expect(width).to.be.within(290 * 0.95 - 1, 290 * 1.05);
 | 
			
		||||
      expect(svg).to.not.have.attr('style');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('V2 - 16: Render Stadium shape', () => {
 | 
			
		||||
@@ -141,7 +138,7 @@ describe('Flowchart v2', () => {
 | 
			
		||||
      class A someclass;
 | 
			
		||||
      class C someclass;
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { htmlLabels: false } , fontFamily: 'courier'}
 | 
			
		||||
      { flowchart: { htmlLabels: false }, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -156,7 +153,7 @@ describe('Flowchart v2', () => {
 | 
			
		||||
        b
 | 
			
		||||
        end
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -171,7 +168,7 @@ describe('Flowchart v2', () => {
 | 
			
		||||
        b
 | 
			
		||||
        end
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -192,7 +189,7 @@ describe('Flowchart v2', () => {
 | 
			
		||||
        B
 | 
			
		||||
    end
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -222,7 +219,7 @@ describe('Flowchart v2', () => {
 | 
			
		||||
  routeur --> subnet1 & subnet2
 | 
			
		||||
  subnet1 & subnet2 --> nat --> internet
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -236,7 +233,7 @@ describe('Flowchart v2', () => {
 | 
			
		||||
     subcontainer-child--> subcontainer-sibling
 | 
			
		||||
  end
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -258,11 +255,10 @@ end
 | 
			
		||||
sub_one --> sub_two
 | 
			
		||||
_one --> b
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  it('56: handle nested subgraphs with outgoing links 3', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `flowchart TB
 | 
			
		||||
@@ -275,7 +271,7 @@ _one --> b
 | 
			
		||||
    end
 | 
			
		||||
    process_B-->|via_AWSBatch|container_Beta
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('57: handle nested subgraphs with outgoing links 4', () => {
 | 
			
		||||
@@ -288,11 +284,10 @@ subgraph B
 | 
			
		||||
b
 | 
			
		||||
end
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  it('57: handle nested subgraphs with outgoing links 2', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `flowchart TB
 | 
			
		||||
@@ -310,7 +305,23 @@ end
 | 
			
		||||
    three --> two
 | 
			
		||||
    two --> c2
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('57.x: handle nested subgraphs with outgoing links 5', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `%% this does not produce the desired result
 | 
			
		||||
flowchart TB
 | 
			
		||||
  subgraph container_Beta
 | 
			
		||||
    process_C-->Process_D
 | 
			
		||||
  end
 | 
			
		||||
  subgraph container_Alpha
 | 
			
		||||
    process_A-->process_B
 | 
			
		||||
    process_B-->|via_AWSBatch|container_Beta
 | 
			
		||||
    process_A-->|messages|process_C
 | 
			
		||||
  end
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('58: handle styling with style expressions', () => {
 | 
			
		||||
@@ -321,7 +332,7 @@ end
 | 
			
		||||
    style id1 fill:#f9f,stroke:#333,stroke-width:4px
 | 
			
		||||
    style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('59: handle styling of subgraphs and links', () => {
 | 
			
		||||
@@ -343,7 +354,37 @@ flowchart TD
 | 
			
		||||
  class T TestSub
 | 
			
		||||
  linkStyle 0,1 color:orange, stroke: orange;
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('60: handle styling for all node shapes - v2', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      flowchart LR
 | 
			
		||||
      A[red text] -->|default style| B(blue text)
 | 
			
		||||
      C([red text]) -->|default style| D[[blue text]]
 | 
			
		||||
      E[(red text)] -->|default style| F((blue text))
 | 
			
		||||
      G>red text] -->|default style| H{blue text}
 | 
			
		||||
      I{{red text}} -->|default style| J[/blue text/]
 | 
			
		||||
      K[\\ red text\\] -->|default style| L[/blue text\\]
 | 
			
		||||
      M[\\ red text/] -->|default style| N[blue text];
 | 
			
		||||
      linkStyle default color:Sienna;
 | 
			
		||||
      style A stroke:#ff0000,fill:#ffcccc,color:#ff0000;
 | 
			
		||||
      style B stroke:#0000ff,fill:#ccccff,color:#0000ff;
 | 
			
		||||
      style C stroke:#ff0000,fill:#ffcccc,color:#ff0000;
 | 
			
		||||
      style D stroke:#0000ff,fill:#ccccff,color:#0000ff;
 | 
			
		||||
      style E stroke:#ff0000,fill:#ffcccc,color:#ff0000;
 | 
			
		||||
      style F stroke:#0000ff,fill:#ccccff,color:#0000ff;
 | 
			
		||||
      style G stroke:#ff0000,fill:#ffcccc,color:#ff0000;
 | 
			
		||||
      style H stroke:#0000ff,fill:#ccccff,color:#0000ff;
 | 
			
		||||
      style I stroke:#ff0000,fill:#ffcccc,color:#ff0000;
 | 
			
		||||
      style J stroke:#0000ff,fill:#ccccff,color:#0000ff;
 | 
			
		||||
      style K stroke:#ff0000,fill:#ffcccc,color:#ff0000;
 | 
			
		||||
      style L stroke:#0000ff,fill:#ccccff,color:#0000ff;
 | 
			
		||||
      style M stroke:#ff0000,fill:#ffcccc,color:#ff0000;
 | 
			
		||||
      style N stroke:#0000ff,fill:#ccccff,color:#0000ff;
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', logLevel: 2 }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('61: fontawesome icons in edge labels', () => {
 | 
			
		||||
@@ -352,9 +393,260 @@ flowchart TD
 | 
			
		||||
      flowchart TD
 | 
			
		||||
        C -->|fa:fa-car Car| F[fa:fa-car Car]
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('62: should render styled subgraphs', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      flowchart TB
 | 
			
		||||
      A
 | 
			
		||||
      B
 | 
			
		||||
      subgraph foo[Foo SubGraph]
 | 
			
		||||
        C
 | 
			
		||||
        D
 | 
			
		||||
      end
 | 
			
		||||
      subgraph bar[Bar SubGraph]
 | 
			
		||||
        E
 | 
			
		||||
        F
 | 
			
		||||
      end
 | 
			
		||||
      G
 | 
			
		||||
 | 
			
		||||
      A-->B
 | 
			
		||||
      B-->C
 | 
			
		||||
      C-->D
 | 
			
		||||
      B-->D
 | 
			
		||||
      D-->E
 | 
			
		||||
      E-->A
 | 
			
		||||
      E-->F
 | 
			
		||||
      F-->D
 | 
			
		||||
      F-->G
 | 
			
		||||
      B-->G
 | 
			
		||||
      G-->D
 | 
			
		||||
 | 
			
		||||
      style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred
 | 
			
		||||
      style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('63: title on subgraphs should be themable', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      %%{init:{"theme":"base", "themeVariables": {"primaryColor":"#411d4e", "titleColor":"white", "darkMode":true}}}%%
 | 
			
		||||
      flowchart LR
 | 
			
		||||
      subgraph A
 | 
			
		||||
          a --> b
 | 
			
		||||
      end
 | 
			
		||||
      subgraph B
 | 
			
		||||
          i -->f
 | 
			
		||||
      end
 | 
			
		||||
      A --> B
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('65: text-color from classes', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      flowchart LR
 | 
			
		||||
        classDef dark fill:#000,stroke:#000,stroke-width:4px,color:#fff
 | 
			
		||||
        Lorem --> Ipsum --> Dolor
 | 
			
		||||
        class Lorem,Dolor dark
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('66: More nested subgraph cases (TB)', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
flowchart TB
 | 
			
		||||
    subgraph two
 | 
			
		||||
    b1
 | 
			
		||||
    end
 | 
			
		||||
    subgraph three
 | 
			
		||||
    c2
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    three --> two
 | 
			
		||||
    two --> c2
 | 
			
		||||
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('67: More nested subgraph cases (RL)', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
flowchart RL
 | 
			
		||||
    subgraph two
 | 
			
		||||
    b1
 | 
			
		||||
    end
 | 
			
		||||
    subgraph three
 | 
			
		||||
    c2
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    three --> two
 | 
			
		||||
    two --> c2
 | 
			
		||||
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('68: More nested subgraph cases (BT)', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
flowchart BT
 | 
			
		||||
    subgraph two
 | 
			
		||||
    b1
 | 
			
		||||
    end
 | 
			
		||||
    subgraph three
 | 
			
		||||
    c2
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    three --> two
 | 
			
		||||
    two --> c2
 | 
			
		||||
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('69: More nested subgraph cases (LR)', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
flowchart LR
 | 
			
		||||
    subgraph two
 | 
			
		||||
    b1
 | 
			
		||||
    end
 | 
			
		||||
    subgraph three
 | 
			
		||||
    c2
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    three --> two
 | 
			
		||||
    two --> c2
 | 
			
		||||
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('70: Handle nested subgraph cases (TB) link out and link between subgraphs', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
flowchart TB
 | 
			
		||||
   subgraph S1
 | 
			
		||||
    sub1 -->sub2
 | 
			
		||||
   end
 | 
			
		||||
  subgraph S2
 | 
			
		||||
    sub4
 | 
			
		||||
   end
 | 
			
		||||
   S1 --> S2
 | 
			
		||||
   sub1 --> sub4
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('71: Handle nested subgraph cases (RL) link out and link between subgraphs', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
flowchart RL
 | 
			
		||||
   subgraph S1
 | 
			
		||||
    sub1 -->sub2
 | 
			
		||||
   end
 | 
			
		||||
  subgraph S2
 | 
			
		||||
    sub4
 | 
			
		||||
   end
 | 
			
		||||
   S1 --> S2
 | 
			
		||||
   sub1 --> sub4
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('72: Handle nested subgraph cases (BT) link out and link between subgraphs', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
flowchart BT
 | 
			
		||||
   subgraph S1
 | 
			
		||||
    sub1 -->sub2
 | 
			
		||||
   end
 | 
			
		||||
  subgraph S2
 | 
			
		||||
    sub4
 | 
			
		||||
   end
 | 
			
		||||
   S1 --> S2
 | 
			
		||||
   sub1 --> sub4
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('74: Handle nested subgraph cases (RL) link out and link between subgraphs', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
flowchart RL
 | 
			
		||||
   subgraph S1
 | 
			
		||||
    sub1 -->sub2
 | 
			
		||||
   end
 | 
			
		||||
  subgraph S2
 | 
			
		||||
    sub4
 | 
			
		||||
   end
 | 
			
		||||
   S1 --> S2
 | 
			
		||||
   sub1 --> sub4
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('74: Handle labels for multiple edges from and to the same couple of nodes', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
flowchart RL
 | 
			
		||||
    subgraph one
 | 
			
		||||
      a1 -- l1 --> a2
 | 
			
		||||
      a1 -- l2 --> a2
 | 
			
		||||
    end
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('76: handle unicode encoded character with HTML labels true', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `flowchart TB
 | 
			
		||||
      a{{"Lorem 'ipsum' dolor 'sit' amet, 'consectetur' adipiscing 'elit'."}}
 | 
			
		||||
      --> b{{"Lorem #quot;ipsum#quot; dolor #quot;sit#quot; amet,#quot;consectetur#quot; adipiscing #quot;elit#quot;."}}
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('2050: handling of different rendering direction in subgraphs', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    flowchart LR
 | 
			
		||||
 | 
			
		||||
      subgraph TOP
 | 
			
		||||
        direction TB
 | 
			
		||||
        subgraph B1
 | 
			
		||||
            direction RL
 | 
			
		||||
            i1 -->f1
 | 
			
		||||
        end
 | 
			
		||||
        subgraph B2
 | 
			
		||||
            direction BT
 | 
			
		||||
            i2 -->f2
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      A --> TOP --> B
 | 
			
		||||
      B1 --> B2
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('2388: handling default in the node name', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      flowchart LR
 | 
			
		||||
      default-index.js --> dot.template.js
 | 
			
		||||
      index.js --> module-utl.js
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
 | 
			
		||||
 | 
			
		||||
describe('Flowchart', () => {
 | 
			
		||||
describe('Graph', () => {
 | 
			
		||||
  it('1: should render a simple flowchart no htmlLabels', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `graph TD
 | 
			
		||||
@@ -38,7 +37,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      C -->|Two| E[iPhone]
 | 
			
		||||
      C -->|Three| F[Car]
 | 
			
		||||
      `,
 | 
			
		||||
      {fontFamily: 'courier'}
 | 
			
		||||
      { fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -53,7 +52,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      C -->|Two| E[\\iPhone\\]
 | 
			
		||||
      C -->|Three| F[Car]
 | 
			
		||||
      `,
 | 
			
		||||
      { fontFamily: 'courier'}
 | 
			
		||||
      { fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -69,7 +68,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      classDef processHead fill:#888888,color:white,font-weight:bold,stroke-width:3px,stroke:#001f3f
 | 
			
		||||
      class 1A,1B,D,E processHead
 | 
			
		||||
      `,
 | 
			
		||||
      {fontFamily: 'courier'}
 | 
			
		||||
      { fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -98,7 +97,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      35(SAM.CommonFA.PopulationFME)-->39(SAM.CommonFA.ChargeDetails)
 | 
			
		||||
      36(SAM.CommonFA.PremetricCost)-->39(SAM.CommonFA.ChargeDetails)
 | 
			
		||||
      `,
 | 
			
		||||
       { fontFamily: 'courier' }
 | 
			
		||||
      { fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -169,7 +168,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      9a072290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
 | 
			
		||||
      9a072290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
 | 
			
		||||
      `,
 | 
			
		||||
       { fontFamily: 'courier' }
 | 
			
		||||
      { fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -178,7 +177,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      `
 | 
			
		||||
    graph TB;subgraph "number as labels";1;end;
 | 
			
		||||
      `,
 | 
			
		||||
       { fontFamily: 'courier' }
 | 
			
		||||
      { fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -190,7 +189,7 @@ describe('Flowchart', () => {
 | 
			
		||||
        a1-->a2
 | 
			
		||||
      end
 | 
			
		||||
      `,
 | 
			
		||||
       { fontFamily: 'courier' }
 | 
			
		||||
      { fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -202,7 +201,7 @@ describe('Flowchart', () => {
 | 
			
		||||
        a1-->a2
 | 
			
		||||
      end
 | 
			
		||||
      `,
 | 
			
		||||
       { fontFamily: 'courier' }
 | 
			
		||||
      { fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -234,10 +233,10 @@ describe('Flowchart', () => {
 | 
			
		||||
      B-->G
 | 
			
		||||
      G-->D
 | 
			
		||||
 | 
			
		||||
      style foo fill:#F99,stroke-width:2px,stroke:#F0F
 | 
			
		||||
      style bar fill:#999,stroke-width:10px,stroke:#0F0
 | 
			
		||||
      style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred
 | 
			
		||||
      style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
 | 
			
		||||
      `,
 | 
			
		||||
       { fontFamily: 'courier' }
 | 
			
		||||
      { fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -339,7 +338,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
 | 
			
		||||
      sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4FC27B48-A6F9-460A-A675-021F5854FE22;
 | 
			
		||||
      `,
 | 
			
		||||
       { fontFamily: 'courier' }
 | 
			
		||||
      { fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -357,7 +356,7 @@ describe('Flowchart', () => {
 | 
			
		||||
        listUrl: false,
 | 
			
		||||
        listId: 'color styling',
 | 
			
		||||
        fontFamily: 'courier',
 | 
			
		||||
        logLevel: 0
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
@@ -379,8 +378,9 @@ describe('Flowchart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      {
 | 
			
		||||
        listUrl: false,
 | 
			
		||||
        listId: 'color styling', fontFamily: 'courier',
 | 
			
		||||
        logLevel: 0
 | 
			
		||||
        listId: 'color styling',
 | 
			
		||||
        fontFamily: 'courier',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
@@ -395,7 +395,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      C -->|Two| E[iPhone]
 | 
			
		||||
      C -->|Three| F[fa:fa-car Car]
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { htmlLabels: false } , fontFamily: 'courier'}
 | 
			
		||||
      { flowchart: { htmlLabels: false }, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -414,7 +414,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      class A someclass;
 | 
			
		||||
      class C someclass;
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { htmlLabels: false } , fontFamily: 'courier'}
 | 
			
		||||
      { flowchart: { htmlLabels: false }, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -431,7 +431,7 @@ describe('Flowchart', () => {
 | 
			
		||||
        linkStyle 1 stroke:DarkGray,stroke-width:2px
 | 
			
		||||
        linkStyle 2 stroke:DarkGray,stroke-width:2px
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { htmlLabels: false } , fontFamily: 'courier'}
 | 
			
		||||
      { flowchart: { htmlLabels: false }, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -440,7 +440,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      `graph LR
 | 
			
		||||
        a --> b --> c
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { htmlLabels: false } , fontFamily: 'courier'}
 | 
			
		||||
      { flowchart: { htmlLabels: false }, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -449,7 +449,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      `graph LR
 | 
			
		||||
        a --> b & c--> d
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { htmlLabels: false } , fontFamily: 'courier'}
 | 
			
		||||
      { flowchart: { htmlLabels: false }, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -459,7 +459,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      A[ h ] -- hello --> B[" test "]:::exClass & C --> D;
 | 
			
		||||
      classDef exClass background:#bbb,border:1px solid red;
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { htmlLabels: false } , fontFamily: 'courier'}
 | 
			
		||||
      { flowchart: { htmlLabels: false }, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -481,7 +481,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      click B testClick "click test"
 | 
			
		||||
      classDef someclass fill:#f96;
 | 
			
		||||
      class A someclass;`,
 | 
			
		||||
      { flowchart: { htmlLabels: false } , fontFamily: 'courier'}
 | 
			
		||||
      { flowchart: { htmlLabels: false }, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -522,7 +522,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      linkStyle 1 stroke:greenyellow,stroke-width:2px
 | 
			
		||||
      style C fill:greenyellow,stroke:green,stroke-width:4px
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { htmlLabels: false } , fontFamily: 'courier'}
 | 
			
		||||
      { flowchart: { htmlLabels: false }, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -545,7 +545,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      click F "javascript:alert('test')" "script test"
 | 
			
		||||
      `,
 | 
			
		||||
      { securityLevel: 'loose', fontFamily: 'courier' }
 | 
			
		||||
      );
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('26: Set text color of nodes and links according to styles when html labels are enabled', () => {
 | 
			
		||||
@@ -584,7 +584,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      click B "index.html#link-clicked" "link test"
 | 
			
		||||
      click D testClick "click test"
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { htmlLabels: false } , fontFamily: 'courier'}
 | 
			
		||||
      { flowchart: { htmlLabels: false }, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -616,7 +616,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      class A myClass1
 | 
			
		||||
      class D myClass2
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { htmlLabels: false } , fontFamily: 'courier'}
 | 
			
		||||
      { flowchart: { htmlLabels: false }, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -640,7 +640,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      classDef redBg fill:#622;
 | 
			
		||||
      classDef whiteTxt color: white;
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { htmlLabels: false } , fontFamily: 'courier'}
 | 
			
		||||
      { flowchart: { htmlLabels: false }, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -652,7 +652,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      eat --> sleep
 | 
			
		||||
      work --> eat
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { htmlLabels: false } , fontFamily: 'courier'}
 | 
			
		||||
      { flowchart: { htmlLabels: false }, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -671,7 +671,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      class A someclass;
 | 
			
		||||
      class C someclass;
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { htmlLabels: false } , fontFamily: 'courier'}
 | 
			
		||||
      { flowchart: { htmlLabels: false }, fontFamily: 'courier' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -694,7 +694,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      `graph TD
 | 
			
		||||
      A[Christmas]
 | 
			
		||||
      `,
 | 
			
		||||
      {  }
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -712,7 +712,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      C -----> E4
 | 
			
		||||
      C ======> E5
 | 
			
		||||
      `,
 | 
			
		||||
      {  }
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('36: should render escaped without html labels', () => {
 | 
			
		||||
@@ -720,7 +720,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      `graph TD
 | 
			
		||||
        a["<strong>Haiya</strong>"]-->b
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: false, flowchart: {htmlLabels: false}}
 | 
			
		||||
      { htmlLabels: false, flowchart: { htmlLabels: false } }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('37: should render non-escaped with html labels', () => {
 | 
			
		||||
@@ -728,7 +728,7 @@ describe('Flowchart', () => {
 | 
			
		||||
      `graph TD
 | 
			
		||||
        a["<strong>Haiya</strong>"]-->b
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('38: should render a flowchart when useMaxWidth is true (default)', () => {
 | 
			
		||||
@@ -742,18 +742,17 @@ describe('Flowchart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { useMaxWidth: true } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
        expect(svg).to.have.attr('height');
 | 
			
		||||
        // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
        const height = parseFloat(svg.attr('height'));
 | 
			
		||||
        expect(height).to.be.within(446 * .95, 446 * 1.05);
 | 
			
		||||
        const style = svg.attr('style');
 | 
			
		||||
        expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
        const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
        expect(maxWidthValue).to.be.within(300 * .95, 300 * 1.05);
 | 
			
		||||
      });
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
      expect(svg).to.have.attr('height');
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
      const height = parseFloat(svg.attr('height'));
 | 
			
		||||
      expect(height).to.be.within(446 * 0.95, 446 * 1.05);
 | 
			
		||||
      const style = svg.attr('style');
 | 
			
		||||
      expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
      const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
      expect(maxWidthValue).to.be.within(300 * 0.95, 300 * 1.05);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  it('39: should render a flowchart when useMaxWidth is false', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
@@ -766,15 +765,14 @@ describe('Flowchart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { flowchart: { useMaxWidth: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        const height = parseFloat(svg.attr('height'));
 | 
			
		||||
        const width = parseFloat(svg.attr('width'));
 | 
			
		||||
        // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
        expect(height).to.be.within(446 * .95, 446 * 1.05);
 | 
			
		||||
        expect(width).to.be.within(300 * .95, 300 * 1.05);
 | 
			
		||||
        expect(svg).to.not.have.attr('style');
 | 
			
		||||
      });
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      const height = parseFloat(svg.attr('height'));
 | 
			
		||||
      const width = parseFloat(svg.attr('width'));
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
      expect(height).to.be.within(446 * 0.95, 446 * 1.05);
 | 
			
		||||
      expect(width).to.be.within(300 * 0.95, 300 * 1.05);
 | 
			
		||||
      expect(svg).to.not.have.attr('style');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  it('58: handle styling with style expressions', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
@@ -784,7 +782,31 @@ describe('Flowchart', () => {
 | 
			
		||||
    style id1 fill:#f9f,stroke:#333,stroke-width:4px
 | 
			
		||||
    style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('60: handle styling for all node shapes', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      graph LR
 | 
			
		||||
      A[red text] -->|default style| B(blue text)
 | 
			
		||||
      C([red text]) -->|default style| D[[blue text]]
 | 
			
		||||
      E[(red text)] -->|default style| F((blue text))
 | 
			
		||||
      G>red text] -->|default style| H{blue text}
 | 
			
		||||
      I{{red text}} -->|default style| J[/blue text/]
 | 
			
		||||
      linkStyle default color:Sienna;
 | 
			
		||||
      style A stroke:#ff0000,fill:#ffcccc,color:#ff0000
 | 
			
		||||
      style B stroke:#0000ff,fill:#ccccff,color:#0000ff
 | 
			
		||||
      style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
 | 
			
		||||
      style D stroke:#0000ff,fill:#ccccff,color:#0000ff
 | 
			
		||||
      style E stroke:#ff0000,fill:#ffcccc,color:#ff0000
 | 
			
		||||
      style F stroke:#0000ff,fill:#ccccff,color:#0000ff
 | 
			
		||||
      style G stroke:#ff0000,fill:#ffcccc,color:#ff0000
 | 
			
		||||
      style H stroke:#0000ff,fill:#ccccff,color:#0000ff
 | 
			
		||||
      style I stroke:#ff0000,fill:#ffcccc,color:#ff0000
 | 
			
		||||
      style J stroke:#0000ff,fill:#ccccff,color:#0000ff
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('61: fontawesome icons in edge labels', () => {
 | 
			
		||||
@@ -793,8 +815,80 @@ describe('Flowchart', () => {
 | 
			
		||||
graph TD
 | 
			
		||||
  C -->|fa:fa-car Car| F[fa:fa-car Car]
 | 
			
		||||
      `,
 | 
			
		||||
      {htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('62: fontawesome icons in edge labels', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    graph TB
 | 
			
		||||
      subgraph bar[Bar]
 | 
			
		||||
        F
 | 
			
		||||
      end
 | 
			
		||||
      style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('63: fontawesome icons in edge labels', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    graph TB
 | 
			
		||||
      A
 | 
			
		||||
      B
 | 
			
		||||
      subgraph foo[Foo SubGraph]
 | 
			
		||||
        C
 | 
			
		||||
        D
 | 
			
		||||
      end
 | 
			
		||||
      subgraph bar[Bar SubGraph]
 | 
			
		||||
        E
 | 
			
		||||
        F
 | 
			
		||||
      end
 | 
			
		||||
      G
 | 
			
		||||
 | 
			
		||||
      A-->B
 | 
			
		||||
      B-->C
 | 
			
		||||
      C-->D
 | 
			
		||||
      B-->D
 | 
			
		||||
      D-->E
 | 
			
		||||
      E-->A
 | 
			
		||||
      E-->F
 | 
			
		||||
      F-->D
 | 
			
		||||
      F-->G
 | 
			
		||||
      B-->G
 | 
			
		||||
      G-->D
 | 
			
		||||
 | 
			
		||||
      style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred
 | 
			
		||||
      style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('64: fontawesome icons in edge labels', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    %%{init:{"theme":"base", "themeVariables": {"primaryColor":"#411d4e", "titleColor":"white", "darkMode":true}}}%%
 | 
			
		||||
    flowchart LR
 | 
			
		||||
    subgraph A
 | 
			
		||||
        a --> b
 | 
			
		||||
    end
 | 
			
		||||
    subgraph B
 | 
			
		||||
        i -->f
 | 
			
		||||
    end
 | 
			
		||||
    A --> B
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('65: text-color from classes', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      flowchart LR
 | 
			
		||||
        classDef dark fill:#000,stroke:#000,stroke-width:4px,color:#fff
 | 
			
		||||
        Lorem --> Ipsum --> Dolor
 | 
			
		||||
        class Lorem,Dolor dark
 | 
			
		||||
      `,
 | 
			
		||||
      { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,9 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
 | 
			
		||||
 | 
			
		||||
describe('Gantt diagram', () => {
 | 
			
		||||
  beforeEach(()=>{
 | 
			
		||||
    cy.clock((new Date('1010-10-10')).getTime())
 | 
			
		||||
  })
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.clock(new Date('1010-10-10').getTime());
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a gantt chart', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
@@ -199,18 +198,17 @@ describe('Gantt diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { gantt: { useMaxWidth: true } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
        expect(svg).to.have.attr('height');
 | 
			
		||||
        // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
        const height = parseFloat(svg.attr('height'));
 | 
			
		||||
        expect(height).to.be.within(484 * .95, 484 * 1.05);
 | 
			
		||||
        const style = svg.attr('style');
 | 
			
		||||
        expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
        const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
        expect(maxWidthValue).to.be.within(984 * .95, 984 * 1.05);
 | 
			
		||||
      });
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
      expect(svg).to.have.attr('height');
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
      const height = parseFloat(svg.attr('height'));
 | 
			
		||||
      expect(height).to.be.within(484 * 0.95, 484 * 1.05);
 | 
			
		||||
      const style = svg.attr('style');
 | 
			
		||||
      expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
      const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
      expect(maxWidthValue).to.be.within(984 * 0.95, 984 * 1.05);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render a gantt diagram when useMaxWidth is false', () => {
 | 
			
		||||
@@ -248,14 +246,49 @@ describe('Gantt diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { gantt: { useMaxWidth: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        const height = parseFloat(svg.attr('height'));
 | 
			
		||||
        const width = parseFloat(svg.attr('width'));
 | 
			
		||||
        // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
        expect(height).to.be.within(484 * .95, 484 * 1.05);
 | 
			
		||||
        expect(width).to.be.within(984 * .95, 984 * 1.05);
 | 
			
		||||
        expect(svg).to.not.have.attr('style');
 | 
			
		||||
      });
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      const height = parseFloat(svg.attr('height'));
 | 
			
		||||
      const width = parseFloat(svg.attr('width'));
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
      expect(height).to.be.within(484 * 0.95, 484 * 1.05);
 | 
			
		||||
      expect(width).to.be.within(984 * 0.95, 984 * 1.05);
 | 
			
		||||
      expect(svg).to.not.have.attr('style');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a gantt diagram with data labels at the top when topAxis is true', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    gantt
 | 
			
		||||
      dateFormat  YYYY-MM-DD
 | 
			
		||||
      axisFormat  %d/%m
 | 
			
		||||
      title Adding GANTT diagram to mermaid
 | 
			
		||||
      excludes weekdays 2014-01-10
 | 
			
		||||
 | 
			
		||||
      section A section
 | 
			
		||||
      Completed task            :done,    des1, 2014-01-06,2014-01-08
 | 
			
		||||
      Active task               :active,  des2, 2014-01-09, 3d
 | 
			
		||||
      Future task               :         des3, after des2, 5d
 | 
			
		||||
      Future task2               :         des4, after des3, 5d
 | 
			
		||||
 | 
			
		||||
      section Critical tasks
 | 
			
		||||
      Completed task in the critical line :crit, done, 2014-01-06,24h
 | 
			
		||||
      Implement parser and jison :crit, done, after des1, 2d
 | 
			
		||||
      Create tests for parser             :crit, active, 3d
 | 
			
		||||
      Future task in critical line        :crit, 5d
 | 
			
		||||
      Create tests for renderer           :2d
 | 
			
		||||
      Add to mermaid                      :1d
 | 
			
		||||
 | 
			
		||||
      section Documentation
 | 
			
		||||
      Describe gantt syntax               :active, a1, after des1, 3d
 | 
			
		||||
      Add gantt diagram to demo page      :after a1  , 20h
 | 
			
		||||
      Add another diagram to demo page    :doc1, after a1  , 48h
 | 
			
		||||
 | 
			
		||||
      section Last section
 | 
			
		||||
      Describe gantt syntax               :after doc1, 3d
 | 
			
		||||
      Add gantt diagram to demo page      : 20h
 | 
			
		||||
      Add another diagram to demo page    : 48h
 | 
			
		||||
      `,
 | 
			
		||||
      { gantt: { topAxis: true } }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { imgSnapshotTest } from '../../helpers/util.js';
 | 
			
		||||
 | 
			
		||||
describe('Sequencediagram', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { imgSnapshotTest } from '../../helpers/util.js';
 | 
			
		||||
 | 
			
		||||
describe('Sequencediagram', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
 | 
			
		||||
 | 
			
		||||
describe('User journey diagram', () => {
 | 
			
		||||
@@ -32,39 +31,36 @@ section Order from website
 | 
			
		||||
  it('should render a user journey diagram when useMaxWidth is true (default)', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `journey
 | 
			
		||||
title Adding journey diagram functionality to mermaid
 | 
			
		||||
title E-Commerce
 | 
			
		||||
section Order from website
 | 
			
		||||
  Add to cart: 5: Me
 | 
			
		||||
section Checkout from website
 | 
			
		||||
  Add payment details: 5: Me
 | 
			
		||||
    `,
 | 
			
		||||
      { journey: { useMaxWidth: true } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
        expect(svg).to.have.attr('height');
 | 
			
		||||
        const height = parseFloat(svg.attr('height'));
 | 
			
		||||
        expect(height).to.eq(20);
 | 
			
		||||
        const style = svg.attr('style');
 | 
			
		||||
        expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
        const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
        expect(maxWidthValue).to.eq(400);
 | 
			
		||||
      });
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
      expect(svg).to.have.attr('height');
 | 
			
		||||
      const height = parseFloat(svg.attr('height'));
 | 
			
		||||
      expect(height).to.eq(565);
 | 
			
		||||
      const style = svg.attr('style');
 | 
			
		||||
      expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
      const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
      expect(maxWidthValue).to.eq(700);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should render a user journey diagram when useMaxWidth is false', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `journey
 | 
			
		||||
title Adding journey diagram functionality to mermaid
 | 
			
		||||
title E-Commerce
 | 
			
		||||
section Order from website
 | 
			
		||||
  Add to cart: 5: Me
 | 
			
		||||
section Checkout from website
 | 
			
		||||
  Add payment details: 5: Me
 | 
			
		||||
    `,
 | 
			
		||||
      { journey: { useMaxWidth: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        const height = parseFloat(svg.attr('height'));
 | 
			
		||||
        const width = parseFloat(svg.attr('width'));
 | 
			
		||||
        expect(height).to.eq(20);
 | 
			
		||||
        expect(width).to.eq(400);
 | 
			
		||||
        expect(svg).to.not.have.attr('style');
 | 
			
		||||
      });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
 | 
			
		||||
 | 
			
		||||
describe('Pie Chart', () => {
 | 
			
		||||
@@ -47,17 +46,16 @@ describe('Pie Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { pie: { useMaxWidth: true } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
        expect(svg).to.have.attr('height');
 | 
			
		||||
        const height = parseFloat(svg.attr('height'));
 | 
			
		||||
        expect(height).to.eq(450);
 | 
			
		||||
        const style = svg.attr('style');
 | 
			
		||||
        expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
        const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
        expect(maxWidthValue).to.eq(984);
 | 
			
		||||
      });
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
      expect(svg).to.have.attr('height');
 | 
			
		||||
      const height = parseFloat(svg.attr('height'));
 | 
			
		||||
      expect(height).to.eq(450);
 | 
			
		||||
      const style = svg.attr('style');
 | 
			
		||||
      expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
      const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
      expect(maxWidthValue).to.eq(984);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a pie diagram when useMaxWidth is false', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
@@ -69,13 +67,12 @@ describe('Pie Chart', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { pie: { useMaxWidth: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        const height = parseFloat(svg.attr('height'));
 | 
			
		||||
        const width = parseFloat(svg.attr('width'));
 | 
			
		||||
        expect(height).to.eq(450);
 | 
			
		||||
        expect(width).to.eq(984);
 | 
			
		||||
        expect(svg).to.not.have.attr('style');
 | 
			
		||||
      });
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      const height = parseFloat(svg.attr('height'));
 | 
			
		||||
      const width = parseFloat(svg.attr('width'));
 | 
			
		||||
      expect(height).to.eq(450);
 | 
			
		||||
      expect(width).to.eq(984);
 | 
			
		||||
      expect(svg).to.not.have.attr('style');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										49
									
								
								cypress/integration/rendering/requirement.spec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								cypress/integration/rendering/requirement.spec.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
 | 
			
		||||
 | 
			
		||||
describe('Requirement diagram', () => {
 | 
			
		||||
  it('sample', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
    requirementDiagram
 | 
			
		||||
 | 
			
		||||
    requirement test_req {
 | 
			
		||||
    id: 1
 | 
			
		||||
    text: the test text.
 | 
			
		||||
    risk: high
 | 
			
		||||
    verifymethod: test
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    functionalRequirement test_req2 {
 | 
			
		||||
    id: 1.1
 | 
			
		||||
    text: the second test text.
 | 
			
		||||
    risk: low
 | 
			
		||||
    verifymethod: inspection
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    performanceRequirement test_req3 {
 | 
			
		||||
    id: 1.2
 | 
			
		||||
    text: the third test text.
 | 
			
		||||
    risk: medium
 | 
			
		||||
    verifymethod: demonstration
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity {
 | 
			
		||||
    type: simulation
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity2 {
 | 
			
		||||
    type: word doc
 | 
			
		||||
    docRef: reqs/test_entity
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    test_entity - satisfies -> test_req2
 | 
			
		||||
    test_req - traces -> test_req2
 | 
			
		||||
    test_req - contains -> test_req3
 | 
			
		||||
    test_req <- copies - test_entity2
 | 
			
		||||
      `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@@ -29,7 +29,7 @@ context('Sequence diagram', () => {
 | 
			
		||||
        Alice -->> John: Parallel message 2
 | 
			
		||||
        end
 | 
			
		||||
      `,
 | 
			
		||||
      {sequence:{actorFontFamily:'courier'}}
 | 
			
		||||
      { sequence: { actorFontFamily: 'courier' } }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should handle different line breaks', () => {
 | 
			
		||||
@@ -52,6 +52,26 @@ context('Sequence diagram', () => {
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should handle line breaks and wrap annotations', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
      participant Alice
 | 
			
		||||
      participant Bob
 | 
			
		||||
      participant John as John<br/>Second Line
 | 
			
		||||
      Alice ->> Bob: Hello Bob, how are you?
 | 
			
		||||
      Bob-->>John: How about you John?
 | 
			
		||||
      Note right of John: John thinks a long<br/>long time, so long<br/>that the text does<br/>not fit on a row.
 | 
			
		||||
      Bob-->Alice: Checking with John...
 | 
			
		||||
      Note over John:wrap: John looks like he's still thinking, so Bob prods him a bit.
 | 
			
		||||
      Bob-x John: Hey John -<br/>we're still waiting to know<br/>how you're doing
 | 
			
		||||
      Note over John:nowrap: John's trying hard not to break his train of thought.
 | 
			
		||||
      Bob-x John:wrap: John! Are you still debating about how you're doing? How long does it take??
 | 
			
		||||
      Note over John: After a few more moments, John<br/>finally snaps out of it.
 | 
			
		||||
    `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('should render loops with a slight margin', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
@@ -127,7 +147,7 @@ context('Sequence diagram', () => {
 | 
			
		||||
        A->>Bob: Hola
 | 
			
		||||
        Bob-->A: Pasten !
 | 
			
		||||
      `,
 | 
			
		||||
        {logLevel: 0}
 | 
			
		||||
        { logLevel: 0 }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should wrap (inline) long actor descriptions', () => {
 | 
			
		||||
@@ -138,7 +158,7 @@ context('Sequence diagram', () => {
 | 
			
		||||
        A->>Bob: Hola
 | 
			
		||||
        Bob-->A: Pasten !
 | 
			
		||||
      `,
 | 
			
		||||
        {logLevel: 0}
 | 
			
		||||
        { logLevel: 0 }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should wrap (directive) long actor descriptions', () => {
 | 
			
		||||
@@ -153,6 +173,18 @@ context('Sequence diagram', () => {
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should be possible to use actor symbols instead of boxes', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        sequenceDiagram
 | 
			
		||||
          actor Alice
 | 
			
		||||
          actor Bob
 | 
			
		||||
          Alice->>Bob: Hi Bob
 | 
			
		||||
          Bob->>Alice: Hi Alice
 | 
			
		||||
      `,
 | 
			
		||||
        {}
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should render long notes left of actor', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
@@ -495,17 +527,17 @@ context('Sequence diagram', () => {
 | 
			
		||||
    });
 | 
			
		||||
    it('should render with an init directive', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
`%%{init: { "theme": "dark", 'config': { "fontFamily": "Menlo", "fontSize": 18, "fontWeight": 400, "wrap": true }}}%%
 | 
			
		||||
        `%%{init: { "theme": "dark", 'config': { "fontFamily": "Menlo", "fontSize": 18, "fontWeight": 400, "wrap": true }}}%%
 | 
			
		||||
          sequenceDiagram
 | 
			
		||||
          Alice->>Bob: Hello Bob, how are you? If you are not available right now, I can leave you a message. Please get back to me as soon as you can!
 | 
			
		||||
          Note left of Alice: Bob thinks
 | 
			
		||||
          Bob->>Alice: Fine!`,
 | 
			
		||||
        {}
 | 
			
		||||
      )
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  context('directives', () => {
 | 
			
		||||
      it('should override config with directive settings', () => {
 | 
			
		||||
    it('should override config with directive settings', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        %%{init: { "config": { "mirrorActors": true }}}%%
 | 
			
		||||
@@ -514,10 +546,13 @@ context('Sequence diagram', () => {
 | 
			
		||||
        note left of Alice: config set to mirrorActors: false<br/>directive set to mirrorActors: true
 | 
			
		||||
        Bob->>Alice: Short as well
 | 
			
		||||
      `,
 | 
			
		||||
        { logLevel:0,  sequence: { mirrorActors: false, noteFontSize: 18, noteFontFamily: 'Arial' } }
 | 
			
		||||
        {
 | 
			
		||||
          logLevel: 0,
 | 
			
		||||
          sequence: { mirrorActors: false, noteFontSize: 18, noteFontFamily: 'Arial' },
 | 
			
		||||
        }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
      it('should override config with directive settings', () => {
 | 
			
		||||
    it('should override config with directive settings', () => {
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        %%{init: { "config": { "mirrorActors": false, "wrap": true }}}%%
 | 
			
		||||
@@ -526,7 +561,53 @@ context('Sequence diagram', () => {
 | 
			
		||||
        note left of Alice: config: mirrorActors=true<br/>directive: mirrorActors=false
 | 
			
		||||
        Bob->>Alice: Short as well
 | 
			
		||||
      `,
 | 
			
		||||
        { logLevel:0,  sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' } }
 | 
			
		||||
        { logLevel: 0, sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' } }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  context('links', () => {
 | 
			
		||||
    it('should support actor links and properties EXPERIMENTAL: USE WITH CAUTION', () => {
 | 
			
		||||
      //Be aware that the syntax for "properties" is likely to be changed.
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        %%{init: { "config": { "mirrorActors": true, "forceMenus": true }}}%%
 | 
			
		||||
        sequenceDiagram
 | 
			
		||||
        participant a as Alice
 | 
			
		||||
        participant j as John
 | 
			
		||||
        note right of a: Hello world!
 | 
			
		||||
        properties a: {"class": "internal-service-actor", "type": "@clock"}
 | 
			
		||||
        properties j: {"class": "external-service-actor", "type": "@computer"}
 | 
			
		||||
        links a: {"Repo": "https://www.contoso.com/repo", "Swagger": "https://www.contoso.com/swagger"}
 | 
			
		||||
        links j: {"Repo": "https://www.contoso.com/repo"}
 | 
			
		||||
        links a: {"Dashboard": "https://www.contoso.com/dashboard", "On-Call": "https://www.contoso.com/oncall"}
 | 
			
		||||
        link a: Contacts @ https://contacts.contoso.com/?contact=alice@contoso.com
 | 
			
		||||
        a->>j: Hello John, how are you?
 | 
			
		||||
        j-->>a: Great!
 | 
			
		||||
      `,
 | 
			
		||||
        { logLevel: 0, sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' } }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    it('should support actor links and properties when not mirrored EXPERIMENTAL: USE WITH CAUTION', () => {
 | 
			
		||||
      //Be aware that the syntax for "properties" is likely to be changed.
 | 
			
		||||
      imgSnapshotTest(
 | 
			
		||||
        `
 | 
			
		||||
        %%{init: { "config": { "mirrorActors": false, "forceMenus": true, "wrap": true }}}%%
 | 
			
		||||
        sequenceDiagram
 | 
			
		||||
        participant a as Alice
 | 
			
		||||
        participant j as John
 | 
			
		||||
        note right of a: Hello world!
 | 
			
		||||
        properties a: {"class": "internal-service-actor", "type": "@clock"}
 | 
			
		||||
        properties j: {"class": "external-service-actor", "type": "@computer"}
 | 
			
		||||
        links a: {"Repo": "https://www.contoso.com/repo", "Swagger": "https://www.contoso.com/swagger"}
 | 
			
		||||
        links j: {"Repo": "https://www.contoso.com/repo"}
 | 
			
		||||
        links a: {"Dashboard": "https://www.contoso.com/dashboard", "On-Call": "https://www.contoso.com/oncall"}
 | 
			
		||||
        a->>j: Hello John, how are you?
 | 
			
		||||
        j-->>a: Great!
 | 
			
		||||
      `,
 | 
			
		||||
        {
 | 
			
		||||
          logLevel: 0,
 | 
			
		||||
          sequence: { mirrorActors: false, noteFontSize: 18, noteFontFamily: 'Arial' },
 | 
			
		||||
        }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
@@ -559,18 +640,17 @@ context('Sequence diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
        { sequence: { useMaxWidth: true } }
 | 
			
		||||
      );
 | 
			
		||||
      cy.get('svg')
 | 
			
		||||
        .should((svg) => {
 | 
			
		||||
          expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
          expect(svg).to.have.attr('height');
 | 
			
		||||
          const height = parseFloat(svg.attr('height'));
 | 
			
		||||
          expect(height).to.eq(920);
 | 
			
		||||
          const style = svg.attr('style');
 | 
			
		||||
          expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
          const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
          // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
          expect(maxWidthValue).to.be.within(820 * .95, 820 * 1.05);
 | 
			
		||||
        });
 | 
			
		||||
      cy.get('svg').should((svg) => {
 | 
			
		||||
        expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
        expect(svg).to.have.attr('height');
 | 
			
		||||
        const height = parseFloat(svg.attr('height'));
 | 
			
		||||
        expect(height).to.be.within(920, 960);
 | 
			
		||||
        const style = svg.attr('style');
 | 
			
		||||
        expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
        const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
        // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
        expect(maxWidthValue).to.be.within(820 * 0.95, 820 * 1.05);
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('should render a sequence diagram when useMaxWidth is false', () => {
 | 
			
		||||
      renderGraph(
 | 
			
		||||
@@ -600,15 +680,14 @@ context('Sequence diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
        { sequence: { useMaxWidth: false } }
 | 
			
		||||
      );
 | 
			
		||||
      cy.get('svg')
 | 
			
		||||
        .should((svg) => {
 | 
			
		||||
          const height = parseFloat(svg.attr('height'));
 | 
			
		||||
          const width = parseFloat(svg.attr('width'));
 | 
			
		||||
          expect(height).to.eq(920);
 | 
			
		||||
          // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
          expect(width).to.be.within(820 * .95, 820 * 1.05);
 | 
			
		||||
          expect(svg).to.not.have.attr('style');
 | 
			
		||||
        });
 | 
			
		||||
      cy.get('svg').should((svg) => {
 | 
			
		||||
        const height = parseFloat(svg.attr('height'));
 | 
			
		||||
        const width = parseFloat(svg.attr('width'));
 | 
			
		||||
        expect(height).to.be.within(920, 960);
 | 
			
		||||
        // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
        expect(width).to.be.within(820 * 0.95, 820 * 1.05);
 | 
			
		||||
        expect(svg).to.not.have.attr('style');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
 | 
			
		||||
 | 
			
		||||
describe('State diagram', () => {
 | 
			
		||||
@@ -329,6 +328,49 @@ describe('State diagram', () => {
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 it should be possibel to use a choice', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
  stateDiagram-v2
 | 
			
		||||
    [*] --> Off
 | 
			
		||||
    Off --> On
 | 
			
		||||
    state MyChoice [[choice]]
 | 
			
		||||
    On --> MyChoice
 | 
			
		||||
    MyChoice --> Washing
 | 
			
		||||
    MyChoice --> Drying
 | 
			
		||||
    Washing --> Finished
 | 
			
		||||
    Finished --> [*]
 | 
			
		||||
    `,
 | 
			
		||||
      {
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 width of compond state should grow with title if title is wider', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
stateDiagram-v2
 | 
			
		||||
  state "Long state name 2" as NotShooting {
 | 
			
		||||
    a-->b
 | 
			
		||||
  }
 | 
			
		||||
    `,
 | 
			
		||||
      {
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 state label with names in it', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
      stateDiagram-v2
 | 
			
		||||
        Yswsii: Your state with spaces in it
 | 
			
		||||
        [*] --> Yswsii
 | 
			
		||||
    `,
 | 
			
		||||
      {
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 Simplest composite state', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
@@ -338,7 +380,8 @@ describe('State diagram', () => {
 | 
			
		||||
        }
 | 
			
		||||
    `,
 | 
			
		||||
      {
 | 
			
		||||
        logLevel: 0, fontFamily: 'courier'
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        fontFamily: 'courier',
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
@@ -350,7 +393,63 @@ describe('State diagram', () => {
 | 
			
		||||
        a --> b: Stop
 | 
			
		||||
    `,
 | 
			
		||||
      {
 | 
			
		||||
        logLevel: 0, fontFamily: 'courier',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        fontFamily: 'courier',
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should handle multiple notes added to one state', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
stateDiagram-v2
 | 
			
		||||
    MyState
 | 
			
		||||
    note left of MyState : I am a leftie
 | 
			
		||||
    note right of MyState : I am a rightie
 | 
			
		||||
    `,
 | 
			
		||||
      {
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        fontFamily: 'courier',
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should handle different rendering directions in composite states', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
stateDiagram-v2
 | 
			
		||||
  direction LR
 | 
			
		||||
  state A {
 | 
			
		||||
    direction BT
 | 
			
		||||
    a --> b
 | 
			
		||||
  }
 | 
			
		||||
  state C {
 | 
			
		||||
    direction RL
 | 
			
		||||
    c --> d
 | 
			
		||||
  }
 | 
			
		||||
  A --> C
 | 
			
		||||
    `,
 | 
			
		||||
      {
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        fontFamily: 'courier',
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 handle transition from one state in a composite state to a composite state', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
stateDiagram-v2
 | 
			
		||||
  state S1 {
 | 
			
		||||
    sub1 -->sub2
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  state S2 {
 | 
			
		||||
    sub4
 | 
			
		||||
  }
 | 
			
		||||
  S1 --> S2
 | 
			
		||||
  sub1 --> sub4
 | 
			
		||||
    `,
 | 
			
		||||
      {
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        fontFamily: 'courier',
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
@@ -364,18 +463,17 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { state: { useMaxWidth: true } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
        expect(svg).to.have.attr('height');
 | 
			
		||||
        const height = parseFloat(svg.attr('height'));
 | 
			
		||||
        expect(height).to.eq(177);
 | 
			
		||||
        const style = svg.attr('style');
 | 
			
		||||
        expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
        const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
        // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
        expect(maxWidthValue).to.be.within(135 * .95, 135 * 1.05);
 | 
			
		||||
      });
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
      expect(svg).to.have.attr('height');
 | 
			
		||||
      const height = parseFloat(svg.attr('height'));
 | 
			
		||||
      expect(height).to.be.within(177, 178);
 | 
			
		||||
      const style = svg.attr('style');
 | 
			
		||||
      expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
      const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
      expect(maxWidthValue).to.be.within(135 * 0.95, 135 * 1.05);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  it('v2 should render a state diagram when useMaxWidth is false', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
@@ -387,14 +485,13 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { state: { useMaxWidth: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        const height = parseFloat(svg.attr('height'));
 | 
			
		||||
        const width = parseFloat(svg.attr('width'));
 | 
			
		||||
        expect(height).to.eq(177);
 | 
			
		||||
        // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
        expect(width).to.be.within(135 * .95, 135 * 1.05);
 | 
			
		||||
        expect(svg).to.not.have.attr('style');
 | 
			
		||||
      });
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      const height = parseFloat(svg.attr('height'));
 | 
			
		||||
      const width = parseFloat(svg.attr('width'));
 | 
			
		||||
      expect(height).to.be.within(177, 178);
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
      expect(width).to.be.within(135 * 0.95, 135 * 1.05);
 | 
			
		||||
      expect(svg).to.not.have.attr('style');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
 | 
			
		||||
 | 
			
		||||
describe('State diagram', () => {
 | 
			
		||||
@@ -315,7 +314,8 @@ describe('State diagram', () => {
 | 
			
		||||
    }
 | 
			
		||||
    `,
 | 
			
		||||
      {
 | 
			
		||||
        logLevel: 0, fontFamily: 'courier'
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        fontFamily: 'courier',
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
@@ -328,7 +328,8 @@ describe('State diagram', () => {
 | 
			
		||||
        }
 | 
			
		||||
    `,
 | 
			
		||||
      {
 | 
			
		||||
        logLevel: 0, fontFamily: 'courier'
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        fontFamily: 'courier',
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
@@ -340,7 +341,8 @@ describe('State diagram', () => {
 | 
			
		||||
        a --> b: Stop
 | 
			
		||||
    `,
 | 
			
		||||
      {
 | 
			
		||||
        logLevel: 0, fontFamily: 'courier'
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        fontFamily: 'courier',
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
@@ -353,18 +355,19 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { state: { useMaxWidth: true } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
        expect(svg).to.have.attr('height');
 | 
			
		||||
        const height = parseFloat(svg.attr('height'));
 | 
			
		||||
        expect(height).to.eq(139);
 | 
			
		||||
        const style = svg.attr('style');
 | 
			
		||||
        expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
        const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
        // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
        expect(maxWidthValue).to.be.within(112 * .95, 112 * 1.05);
 | 
			
		||||
      });
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      expect(svg).to.have.attr('width', '100%');
 | 
			
		||||
      expect(svg).to.have.attr('height');
 | 
			
		||||
      const height = parseFloat(svg.attr('height'));
 | 
			
		||||
      expect(height).to.be.within(176, 178);
 | 
			
		||||
      const style = svg.attr('style');
 | 
			
		||||
      expect(style).to.match(/^max-width: [\d.]+px;$/);
 | 
			
		||||
      const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
      // Todo investigate difference
 | 
			
		||||
      // expect(maxWidthValue).to.be.within(112 * .95, 112 * 1.05);
 | 
			
		||||
      expect(maxWidthValue).to.be.within(130, 140);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  it('should render a state diagram when useMaxWidth is false', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
@@ -375,14 +378,16 @@ describe('State diagram', () => {
 | 
			
		||||
      `,
 | 
			
		||||
      { state: { useMaxWidth: false } }
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg')
 | 
			
		||||
      .should((svg) => {
 | 
			
		||||
        const height = parseFloat(svg.attr('height'));
 | 
			
		||||
        const width = parseFloat(svg.attr('width'));
 | 
			
		||||
        expect(height).to.eq(139);
 | 
			
		||||
        // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
        expect(width).to.be.within(112 * .95, 112 * 1.05);
 | 
			
		||||
        expect(svg).to.not.have.attr('style');
 | 
			
		||||
      });
 | 
			
		||||
    cy.get('svg').should((svg) => {
 | 
			
		||||
      const height = parseFloat(svg.attr('height'));
 | 
			
		||||
      const width = parseFloat(svg.attr('width'));
 | 
			
		||||
      expect(height).to.be.within(176, 178);
 | 
			
		||||
      // use within because the absolute value can be slightly different depending on the environment ±5%
 | 
			
		||||
      // Todo investigate difference
 | 
			
		||||
      // expect(width).to.be.within(112 * .95, 112 * 1.05);
 | 
			
		||||
      expect(width).to.be.within(130, 140);
 | 
			
		||||
 | 
			
		||||
      expect(svg).to.not.have.attr('style');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,36 @@
 | 
			
		||||
/* eslint-env jest */
 | 
			
		||||
import { imgSnapshotTest } from '../../helpers/util.js';
 | 
			
		||||
 | 
			
		||||
describe('Pie Chart', () => {
 | 
			
		||||
    // beforeEach(()=>{
 | 
			
		||||
    //   cy.clock((new Date('2014-06-09')).getTime());
 | 
			
		||||
    // });
 | 
			
		||||
describe('themeCSS balancing, it', () => {
 | 
			
		||||
  it('should not allow unbalanced CSS definitions', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
  %%{init: { 'themeCSS': '} * { background: red }' } }%%
 | 
			
		||||
  flowchart TD
 | 
			
		||||
    a --> b
 | 
			
		||||
          `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
  it('should not allow unbalanced CSS definitions 2', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
      `
 | 
			
		||||
  %%{init: { 'themeCSS': '\u007D * { background: red }' } }%%
 | 
			
		||||
  flowchart TD
 | 
			
		||||
    a2 --> b2
 | 
			
		||||
          `,
 | 
			
		||||
      {}
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg');
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
  ['default', 'forest', 'dark', 'neutral'].forEach(theme=>{
 | 
			
		||||
describe('Pie Chart', () => {
 | 
			
		||||
  // beforeEach(()=>{
 | 
			
		||||
  //   cy.clock((new Date('2014-06-09')).getTime());
 | 
			
		||||
  // });
 | 
			
		||||
 | 
			
		||||
  ['default', 'forest', 'dark', 'neutral'].forEach((theme) => {
 | 
			
		||||
    describe(theme, () => {
 | 
			
		||||
      it('should render a pie diagram', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
@@ -16,7 +40,7 @@ describe('Pie Chart', () => {
 | 
			
		||||
          "Ice-Hockey" : 80
 | 
			
		||||
          "Football" : 90
 | 
			
		||||
          `,
 | 
			
		||||
          {theme}
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
      });
 | 
			
		||||
@@ -39,7 +63,7 @@ describe('Pie Chart', () => {
 | 
			
		||||
            G
 | 
			
		||||
          end
 | 
			
		||||
          `,
 | 
			
		||||
          {theme}
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
      });
 | 
			
		||||
@@ -62,7 +86,7 @@ describe('Pie Chart', () => {
 | 
			
		||||
            G
 | 
			
		||||
          end
 | 
			
		||||
          `,
 | 
			
		||||
          {theme}
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
      });
 | 
			
		||||
@@ -88,7 +112,7 @@ describe('Pie Chart', () => {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
          `,
 | 
			
		||||
          {theme}
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
      });
 | 
			
		||||
@@ -135,10 +159,10 @@ describe('Pie Chart', () => {
 | 
			
		||||
        classM ..|> classN : Realization
 | 
			
		||||
        classO .. classP : Link(Dashed)
 | 
			
		||||
          `,
 | 
			
		||||
          {theme}
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
    });
 | 
			
		||||
      });
 | 
			
		||||
      it('should render a state diagram', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
          `
 | 
			
		||||
@@ -167,10 +191,10 @@ stateDiagram
 | 
			
		||||
        Active --> SomethingElse
 | 
			
		||||
        note right of SomethingElse : This is the note to the right.
 | 
			
		||||
          `,
 | 
			
		||||
          {theme}
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
    });
 | 
			
		||||
      });
 | 
			
		||||
      it('should render a state diagram (v2)', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
          `
 | 
			
		||||
@@ -199,10 +223,10 @@ stateDiagram-v2
 | 
			
		||||
        Active --> SomethingElse2
 | 
			
		||||
        note right of SomethingElse2 : This is the note to the right.
 | 
			
		||||
          `,
 | 
			
		||||
          {theme}
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
    });
 | 
			
		||||
      });
 | 
			
		||||
      it('should render a er diagram', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
          `
 | 
			
		||||
@@ -217,10 +241,10 @@ erDiagram
 | 
			
		||||
        PRODUCT ||--o{ ORDER-ITEM : "ordered in"
 | 
			
		||||
 | 
			
		||||
          `,
 | 
			
		||||
          {theme}
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
    });
 | 
			
		||||
      });
 | 
			
		||||
      it('should render a user journey diagram', () => {
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
          `
 | 
			
		||||
@@ -235,12 +259,12 @@ erDiagram
 | 
			
		||||
              Go downstairs: 5: Me
 | 
			
		||||
              Sit down: 5: Me
 | 
			
		||||
                        `,
 | 
			
		||||
          {theme}
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
    });
 | 
			
		||||
      });
 | 
			
		||||
      it('should render a gantt diagram', () => {
 | 
			
		||||
        cy.clock((new Date('2014-01-06')).getTime());
 | 
			
		||||
        cy.clock(new Date('2014-01-06').getTime());
 | 
			
		||||
        imgSnapshotTest(
 | 
			
		||||
          `
 | 
			
		||||
      gantt
 | 
			
		||||
@@ -271,10 +295,10 @@ erDiagram
 | 
			
		||||
       Add gantt diagram to demo page      :20h
 | 
			
		||||
       Add another diagram to demo page    :48h
 | 
			
		||||
       `,
 | 
			
		||||
          {theme}
 | 
			
		||||
          { theme }
 | 
			
		||||
        );
 | 
			
		||||
        cy.get('svg');
 | 
			
		||||
    });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -36,23 +36,23 @@ mermaid.initialize({
 | 
			
		||||
  startOnLoad: false,
 | 
			
		||||
  securityLevel: 'loose',
 | 
			
		||||
  flowchart: {
 | 
			
		||||
    htmlLabels: true
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
  },
 | 
			
		||||
  gantt: {
 | 
			
		||||
    axisFormatter: [
 | 
			
		||||
      [
 | 
			
		||||
        '%Y-%m-%d',
 | 
			
		||||
        d => {
 | 
			
		||||
        (d) => {
 | 
			
		||||
          return d.getDay() === 1;
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
mermaid.render(
 | 
			
		||||
  'the-id-of-the-svg',
 | 
			
		||||
  code,
 | 
			
		||||
  svg => {
 | 
			
		||||
  (svg) => {
 | 
			
		||||
    console.log(svg);
 | 
			
		||||
    const elem = document.querySelector('#graph-to-be');
 | 
			
		||||
    elem.innerHTML = svg;
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@
 | 
			
		||||
        +withdrawl(amount) int
 | 
			
		||||
       }
 | 
			
		||||
       cssClass "BankAccount" customCss
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="mermaid" style="width: 100%; height: 20%;">
 | 
			
		||||
      %%{init: {'theme': 'base',  'fontFamily': 'courier', 'themeVariables': {  'primaryColor': '#fff000'}}}%%
 | 
			
		||||
@@ -47,7 +47,7 @@
 | 
			
		||||
        +withdrawl(amount) int
 | 
			
		||||
       }
 | 
			
		||||
       cssClass "BankAccount" customCss
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
    </div>
 | 
			
		||||
      <div class="mermaid2" style="width: 100%; height: 20%;">
 | 
			
		||||
        %%{init: {'theme': 'base',  'fontFamily': 'courier', 'themeVariables': {  'primaryColor': '#fff000'}}}%%
 | 
			
		||||
@@ -69,8 +69,8 @@
 | 
			
		||||
              int id
 | 
			
		||||
              test()
 | 
			
		||||
            }
 | 
			
		||||
            callback Class01 "callback" "A Tooltip"  
 | 
			
		||||
     
 | 
			
		||||
            callback Class01 "callback" "A Tooltip"
 | 
			
		||||
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="mermaid2" style="width: 100%; height: 20%;">
 | 
			
		||||
      flowchart TB
 | 
			
		||||
@@ -79,7 +79,7 @@
 | 
			
		||||
      classDef apa fill:#f9f,stroke:#333,stroke-width:4px;
 | 
			
		||||
      class a_a apa;
 | 
			
		||||
      click a_a "http://www.aftonbladet.se" "apa"
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="mermaid2" style="width: 100%; height: 20%;">
 | 
			
		||||
@@ -110,19 +110,19 @@
 | 
			
		||||
 | 
			
		||||
        class Shape
 | 
			
		||||
        callback Shape "callbackFunction" "This is a tooltip for a callback"
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
      </div>
 | 
			
		||||
      <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
          // console.error('Mermaid error: ', err);
 | 
			
		||||
        };
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'default',
 | 
			
		||||
        // arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        flowchart: { curve: 'linear', "htmlLabels": true },
 | 
			
		||||
        flowchart: { curve: 'linear', htmlLabels: true },
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorMargin: 50, showSequenceNumbers: true },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
@@ -131,9 +131,11 @@
 | 
			
		||||
        //   fontFamily: '"arial", sans-serif',
 | 
			
		||||
        // },
 | 
			
		||||
        curve: 'linear',
 | 
			
		||||
        securityLevel: 'loose'
 | 
			
		||||
        securityLevel: 'loose',
 | 
			
		||||
      });
 | 
			
		||||
      function callback(){alert('It worked');}
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -95,35 +95,74 @@
 | 
			
		||||
    Add gantt diagram to demo page      : 20h
 | 
			
		||||
    Add another diagram to demo page    : 48h
 | 
			
		||||
      </div>
 | 
			
		||||
  <div style="display: flex">
 | 
			
		||||
    <div id="FirstLine" class="mermaid">
 | 
			
		||||
      graph TB
 | 
			
		||||
        FunctionArg-->URL
 | 
			
		||||
        click FunctionArg call clickByFlowArg(ARGUMENT) "Add a div"
 | 
			
		||||
        click URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
 | 
			
		||||
    </div>
 | 
			
		||||
    <div id="FirstLine" class="mermaid">
 | 
			
		||||
      flowchart TB
 | 
			
		||||
        FunctionArg-->URL
 | 
			
		||||
        click FunctionArg call clickByFlowArg(ARGUMENT) "Add a div"
 | 
			
		||||
        click URL "http://localhost:9000/webpackUsage.html" "Visit <strong>mermaid docs</strong>"
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
    <div id="FirstLine" class="mermaid">
 | 
			
		||||
      classDiagram
 | 
			
		||||
      class ShapeLink
 | 
			
		||||
      link ShapeLink "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
 | 
			
		||||
      class ShapeCallback
 | 
			
		||||
      click ShapeCallback call clickByClass(123) "This is a tooltip for a callback"
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div id="FirstLine" class="mermaid">
 | 
			
		||||
      classDiagram-v2
 | 
			
		||||
        class ShapeLink2
 | 
			
		||||
        link ShapeLink2 "http://localhost:9000/webpackUsage.html" "This is a tooltip for a link"
 | 
			
		||||
        class ShapeCallback2
 | 
			
		||||
        click ShapeCallback2 call clickByClass(123) "This is a tooltip for a callback"
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
  </div>
 | 
			
		||||
    
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
  <script>
 | 
			
		||||
  function clickByFlow(elemName) {
 | 
			
		||||
    const div = document.createElement('div')
 | 
			
		||||
    div.className = 'created-by-click'
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;'
 | 
			
		||||
    div.innerText = 'Clicked By Flow'
 | 
			
		||||
    const div = document.createElement('div');
 | 
			
		||||
    div.className = 'created-by-click';
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;';
 | 
			
		||||
    div.innerText = 'Clicked By Flow';
 | 
			
		||||
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div)
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
  }
 | 
			
		||||
  function clickByFlowArg(argument) {
 | 
			
		||||
    const div = document.createElement('div');
 | 
			
		||||
    div.className = 'created-by-click-2';
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;';
 | 
			
		||||
    div.innerText = 'Clicked By Flow: ' + argument;
 | 
			
		||||
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
  }
 | 
			
		||||
  function clickByGantt(arg1, arg2, arg3) {
 | 
			
		||||
    const div = document.createElement('div')
 | 
			
		||||
    div.className = 'created-by-gant-click'
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;'
 | 
			
		||||
    div.innerText = 'Clicked By Gant'
 | 
			
		||||
    const div = document.createElement('div');
 | 
			
		||||
    div.className = 'created-by-gant-click';
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;';
 | 
			
		||||
    div.innerText = 'Clicked By Gant';
 | 
			
		||||
    if (arg1) div.innerText += ' ' + arg1;
 | 
			
		||||
    if (arg2) div.innerText += ' ' + arg2;
 | 
			
		||||
    if (arg3) div.innerText += ' ' + arg3;
 | 
			
		||||
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div)
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
  }
 | 
			
		||||
  function clickByClass() {
 | 
			
		||||
    const div = document.createElement('div')
 | 
			
		||||
    div.className = 'created-by-class-click'
 | 
			
		||||
    div.style = 'padding: 20px; background: purple; color: white;'
 | 
			
		||||
    div.innerText = 'Clicked By Class'
 | 
			
		||||
  function clickByClass(arg) {
 | 
			
		||||
    const div = document.createElement('div');
 | 
			
		||||
    div.className = 'created-by-class-click';
 | 
			
		||||
    div.style = 'padding: 20px; background: purple; color: white;';
 | 
			
		||||
    div.innerText = 'Clicked By Class' + (arg ? arg : '');
 | 
			
		||||
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div)
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
  }
 | 
			
		||||
  mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 });
 | 
			
		||||
  </script>
 | 
			
		||||
 
 | 
			
		||||
@@ -62,20 +62,20 @@
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
  <script>
 | 
			
		||||
  function clickByFlow(elemName) {
 | 
			
		||||
    const div = document.createElement('div')
 | 
			
		||||
    div.className = 'created-by-click'
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;'
 | 
			
		||||
    div.innerText = 'Clicked By Flow'
 | 
			
		||||
    const div = document.createElement('div');
 | 
			
		||||
    div.className = 'created-by-click';
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;';
 | 
			
		||||
    div.innerText = 'Clicked By Flow';
 | 
			
		||||
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div)
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
  }
 | 
			
		||||
  function clickByGantt(elemName) {
 | 
			
		||||
    const div = document.createElement('div')
 | 
			
		||||
    div.className = 'created-by-gant-click'
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;'
 | 
			
		||||
    div.innerText = 'Clicked By Gant'
 | 
			
		||||
    const div = document.createElement('div');
 | 
			
		||||
    div.className = 'created-by-gant-click';
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;';
 | 
			
		||||
    div.innerText = 'Clicked By Gant';
 | 
			
		||||
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div)
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
  }
 | 
			
		||||
  mermaid.initialize({ startOnLoad: true, securityLevel: 'strct', logLevel: 1 });
 | 
			
		||||
  </script>
 | 
			
		||||
 
 | 
			
		||||
@@ -64,23 +64,23 @@
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
  <script>
 | 
			
		||||
  function clickByFlow(elemName) {
 | 
			
		||||
    const div = document.createElement('div')
 | 
			
		||||
    div.className = 'created-by-click'
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;'
 | 
			
		||||
    div.innerText = 'Clicked By Flow'
 | 
			
		||||
    const div = document.createElement('div');
 | 
			
		||||
    div.className = 'created-by-click';
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;';
 | 
			
		||||
    div.innerText = 'Clicked By Flow';
 | 
			
		||||
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div)
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
  }
 | 
			
		||||
  function clickByGantt(arg1, arg2, arg3) {
 | 
			
		||||
    const div = document.createElement('div')
 | 
			
		||||
    div.className = 'created-by-gant-click'
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;'
 | 
			
		||||
    div.innerText = 'Clicked By Gant'
 | 
			
		||||
    const div = document.createElement('div');
 | 
			
		||||
    div.className = 'created-by-gant-click';
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;';
 | 
			
		||||
    div.innerText = 'Clicked By Gant';
 | 
			
		||||
    if (arg1) div.innerText += ' ' + arg1;
 | 
			
		||||
    if (arg2) div.innerText += ' ' + arg2;
 | 
			
		||||
    if (arg3) div.innerText += ' ' + arg3;
 | 
			
		||||
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div)
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
  }
 | 
			
		||||
  mermaid.initialize({ startOnLoad: true, securityLevel: 'strict', logLevel: 1 });
 | 
			
		||||
  </script>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								cypress/platform/css1.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								cypress/platform/css1.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
  <meta charset="utf-8">
 | 
			
		||||
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
 | 
			
		||||
  <title>Mermaid Quick Test Page</title>
 | 
			
		||||
  <link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
 | 
			
		||||
  <style>
 | 
			
		||||
    body {
 | 
			
		||||
      font-family: 'trebuchet ms', verdana, arial;
 | 
			
		||||
    }
 | 
			
		||||
  </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
  <div class="mermaid2">
 | 
			
		||||
  %%{init: { 'themeCSS': '} * { background: lightblue }' } }%%
 | 
			
		||||
  flowchart TD
 | 
			
		||||
    a --> b
 | 
			
		||||
  </div>
 | 
			
		||||
  <div class="mermaid">
 | 
			
		||||
   %%{init:{"theme":"base", "themeVariables": {"primaryColor":"#411d4e", "titleColor":"white", "darkMode":true}}}%%
 | 
			
		||||
    flowchart LR
 | 
			
		||||
    subgraph A
 | 
			
		||||
        a --> b
 | 
			
		||||
    end
 | 
			
		||||
    subgraph B
 | 
			
		||||
        i -->f
 | 
			
		||||
    end
 | 
			
		||||
    A --> B
 | 
			
		||||
  </div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
  <script>
 | 
			
		||||
     function showFullFirstSquad(elemName) {
 | 
			
		||||
       console.log('show ' + elemName);
 | 
			
		||||
     }
 | 
			
		||||
     mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 0 });
 | 
			
		||||
  </script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -74,7 +74,7 @@ stateDiagram-v2
 | 
			
		||||
  A --> D: asd123
 | 
			
		||||
      </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="mermaid" style="width: 50%; height: 40%;">
 | 
			
		||||
      <div class="mermaid2" style="width: 50%; height: 40%;">
 | 
			
		||||
%% this does not produce the desired result
 | 
			
		||||
flowchart TB
 | 
			
		||||
  subgraph container_Beta
 | 
			
		||||
@@ -88,24 +88,13 @@ flowchart TB
 | 
			
		||||
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="mermaid" style="width: 50%; height: 40%;">
 | 
			
		||||
        %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%%
 | 
			
		||||
flowchart TB
 | 
			
		||||
    b-->B
 | 
			
		||||
    a-->c
 | 
			
		||||
    subgraph O
 | 
			
		||||
      A
 | 
			
		||||
    end
 | 
			
		||||
    subgraph B
 | 
			
		||||
      c
 | 
			
		||||
    end
 | 
			
		||||
    subgraph A
 | 
			
		||||
        a
 | 
			
		||||
        b
 | 
			
		||||
        B
 | 
			
		||||
    end
 | 
			
		||||
        flowchart TB
 | 
			
		||||
	a{{"Lorem 'ipsum' dolor 'sit' amet, 'consectetur' adipiscing 'elit'."}}
 | 
			
		||||
	--> b{{"Lorem #quot;ipsum#quot; dolor #quot;sit#quot; amet,#quot;consectetur#quot; adipiscing #quot;elit#quot;."}}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="mermaid" style="width: 50%; height: 50%;">
 | 
			
		||||
      <div class="mermaid2" style="width: 50%; height: 50%;">
 | 
			
		||||
flowchart TB
 | 
			
		||||
  internet
 | 
			
		||||
  nat
 | 
			
		||||
@@ -130,7 +119,7 @@ flowchart TB
 | 
			
		||||
  routeur --> subnet1 & subnet2
 | 
			
		||||
  subnet1 & subnet2 --> nat --> internet
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="mermaid" style="width: 50%; height: 50%;">
 | 
			
		||||
      <div class="mermaid2" style="width: 50%; height: 50%;">
 | 
			
		||||
flowchart TD
 | 
			
		||||
 | 
			
		||||
subgraph one[One]
 | 
			
		||||
@@ -145,7 +134,7 @@ end
 | 
			
		||||
 | 
			
		||||
sub_one --> two
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="mermaid" style="width: 50%; height: 50%;">
 | 
			
		||||
      <div class="mermaid2" style="width: 50%; height: 50%;">
 | 
			
		||||
flowchart TD
 | 
			
		||||
 | 
			
		||||
subgraph one[One]
 | 
			
		||||
@@ -166,23 +155,25 @@ _one --> b
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
          // console.error('Mermaid error: ', err);
 | 
			
		||||
        };
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        // theme: 'forest',
 | 
			
		||||
        // themeVariables:{primaryColor: '#ff0000'},
 | 
			
		||||
        // arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        flowchart: { curve: 'cardinal', "htmlLabels": false },
 | 
			
		||||
        flowchart: { curve: 'cardinal', htmlLabels: true },
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorMargin: 50, showSequenceNumbers: true },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        fontFamily: '"arial", sans-serif',
 | 
			
		||||
        curve: 'cardinal',
 | 
			
		||||
        securityLevel: 'strict'
 | 
			
		||||
        securityLevel: 'strict',
 | 
			
		||||
      });
 | 
			
		||||
      function callback(){alert('It worked');}
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -107,23 +107,25 @@ Note over Bob,Alice: Looks back
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
          // console.error('Mermaid error: ', err);
 | 
			
		||||
        };
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        // theme: 'forest',
 | 
			
		||||
        // themeVariables:{primaryColor: '#ff0000'},
 | 
			
		||||
        // arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        flowchart: { curve: 'cardinal', "htmlLabels": false },
 | 
			
		||||
        flowchart: { curve: 'cardinal', htmlLabels: false },
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorMargin: 50, showSequenceNumbers: true },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        fontFamily: '"arial", sans-serif',
 | 
			
		||||
        curve: 'cardinal',
 | 
			
		||||
        securityLevel: 'strict'
 | 
			
		||||
        securityLevel: 'strict',
 | 
			
		||||
      });
 | 
			
		||||
      function callback(){alert('It worked');}
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,52 +1,52 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="utf-8"/>
 | 
			
		||||
    <!-- <meta charset="iso-8859-15"/> -->
 | 
			
		||||
    <script src="/e2e.js"></script>
 | 
			
		||||
    <!-- <link href="https://fonts.googleapis.com/css?family=Mansalva&display=swap" rel="stylesheet" /> -->
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* font-family: 'Mansalva', cursive;*/
 | 
			
		||||
        /* font-family: 'Mansalva', cursive; */
 | 
			
		||||
        /* font-family: 'arial'; */
 | 
			
		||||
        /* font-family: "trebuchet ms", verdana, arial; */
 | 
			
		||||
      }
 | 
			
		||||
      /* div {
 | 
			
		||||
        font-family: 'arial';
 | 
			
		||||
      } */
 | 
			
		||||
      /* .mermaid-main-font {
 | 
			
		||||
        font-family: "trebuchet ms", verdana, arial;
 | 
			
		||||
        font-family: var(--mermaid-font-family);
 | 
			
		||||
      } */
 | 
			
		||||
      /* :root {
 | 
			
		||||
        --mermaid-font-family: '"trebuchet ms", verdana, arial';
 | 
			
		||||
        --mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive;
 | 
			
		||||
        --mermaid-font-family: '"Lucida Console", Monaco, monospace';
 | 
			
		||||
      } */
 | 
			
		||||
      svg {
 | 
			
		||||
        border: 2px solid darkred;
 | 
			
		||||
      }
 | 
			
		||||
      .exClass2 > rect, .exClass {
 | 
			
		||||
        fill: greenyellow !important;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      // Notice startOnLoad=false
 | 
			
		||||
      // This prevents default handling in mermaid from render before the e2e logic is applied
 | 
			
		||||
      // mermaid.initialize({
 | 
			
		||||
      //   startOnLoad: false,
 | 
			
		||||
      //   useMaxWidth: true,
 | 
			
		||||
      //   // "themeCSS": ":root { --mermaid-font-family: \"trebuchet ms\", verdana, arial;}",
 | 
			
		||||
      //   // fontFamily: '\"trebuchet ms\", verdana, arial;'
 | 
			
		||||
      //   // fontFamily: '"Comic Sans MS", "Comic Sans", cursive'
 | 
			
		||||
      //   // fontFamily: '"Mansalva", cursive',
 | 
			
		||||
      //   // fontFamily: '"Noto Sans SC", sans-serif'
 | 
			
		||||
      //   fontFamily: '"Noto Sans SC", sans-serif'
 | 
			
		||||
      // });
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="utf-8"/>
 | 
			
		||||
    <!-- <meta charset="iso-8859-15"/> -->
 | 
			
		||||
    <script src="/e2e.js"></script>
 | 
			
		||||
    <!-- <link href="https://fonts.googleapis.com/css?family=Mansalva&display=swap" rel="stylesheet" /> -->
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* font-family: 'Mansalva', cursive;*/
 | 
			
		||||
        /* font-family: 'Mansalva', cursive; */
 | 
			
		||||
        /* font-family: 'arial'; */
 | 
			
		||||
        /* font-family: "trebuchet ms", verdana, arial; */
 | 
			
		||||
      }
 | 
			
		||||
      /* div {
 | 
			
		||||
        font-family: 'arial';
 | 
			
		||||
      } */
 | 
			
		||||
      /* .mermaid-main-font {
 | 
			
		||||
        font-family: "trebuchet ms", verdana, arial;
 | 
			
		||||
        font-family: var(--mermaid-font-family);
 | 
			
		||||
      } */
 | 
			
		||||
      /* :root {
 | 
			
		||||
        --mermaid-font-family: '"trebuchet ms", verdana, arial';
 | 
			
		||||
        --mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive;
 | 
			
		||||
        --mermaid-font-family: '"Lucida Console", Monaco, monospace';
 | 
			
		||||
      } */
 | 
			
		||||
      svg {
 | 
			
		||||
        border: 2px solid darkred;
 | 
			
		||||
      }
 | 
			
		||||
      .exClass2 > rect, .exClass {
 | 
			
		||||
        fill: greenyellow !important;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      // Notice startOnLoad=false
 | 
			
		||||
      // This prevents default handling in mermaid from render before the e2e logic is applied
 | 
			
		||||
      // mermaid.initialize({
 | 
			
		||||
      //   startOnLoad: false,
 | 
			
		||||
      //   useMaxWidth: true,
 | 
			
		||||
      //   // "themeCSS": ":root { --mermaid-font-family: \"trebuchet ms\", verdana, arial;}",
 | 
			
		||||
      //   // fontFamily: '\"trebuchet ms\", verdana, arial;'
 | 
			
		||||
      //   // fontFamily: '"Comic Sans MS", "Comic Sans", cursive'
 | 
			
		||||
      //   // fontFamily: '"Mansalva", cursive',
 | 
			
		||||
      //   // fontFamily: '"Noto Sans SC", sans-serif'
 | 
			
		||||
      //   fontFamily: '"Noto Sans SC", sans-serif'
 | 
			
		||||
      // });
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								cypress/platform/exploit.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								cypress/platform/exploit.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
const div = parent.document.createElement('div');
 | 
			
		||||
div.id = 'the-malware';
 | 
			
		||||
div.className = 'malware';
 | 
			
		||||
div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
parent.document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
throw new Error('XSS Succeded');
 | 
			
		||||
@@ -1,46 +1,46 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <style>body {
 | 
			
		||||
      font-family: 'trebuchet ms', verdana, arial;
 | 
			
		||||
    }</style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div class="mermaid">
 | 
			
		||||
      graph TB
 | 
			
		||||
      subgraph One
 | 
			
		||||
        a1-->a2-->a3
 | 
			
		||||
      end
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="mermaid">
 | 
			
		||||
      graph TB
 | 
			
		||||
        a_a --> b_b:::apa --> c_c:::apa
 | 
			
		||||
        classDef apa fill:#f9f,stroke:#333,stroke-width:4px;
 | 
			
		||||
        class a_a apa;
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="mermaid">
 | 
			
		||||
      graph TB
 | 
			
		||||
        a_a(Aftonbladet) --> b_b[gorilla]:::apa --> c_c{chimp}:::apa -->a_a
 | 
			
		||||
        a_a --> c --> d_d --> c_c
 | 
			
		||||
        classDef apa fill:#f9f,stroke:#333,stroke-width:4px;
 | 
			
		||||
        class a_a apa;
 | 
			
		||||
        click a_a "http://www.aftonbladet.se" "apa"
 | 
			
		||||
    </div>
 | 
			
		||||
    <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        // themeCSS: '.node rect { fill: red; }',
 | 
			
		||||
        logLevel: 3,
 | 
			
		||||
        flowchart: { curve: 'linear' },
 | 
			
		||||
        gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorMargin: 50 },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
      });
 | 
			
		||||
    </script>
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <style>body {
 | 
			
		||||
      font-family: 'trebuchet ms', verdana, arial;
 | 
			
		||||
    }</style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div class="mermaid">
 | 
			
		||||
      graph TB
 | 
			
		||||
      subgraph One
 | 
			
		||||
        a1-->a2-->a3
 | 
			
		||||
      end
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="mermaid">
 | 
			
		||||
      graph TB
 | 
			
		||||
        a_a --> b_b:::apa --> c_c:::apa
 | 
			
		||||
        classDef apa fill:#f9f,stroke:#333,stroke-width:4px;
 | 
			
		||||
        class a_a apa;
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="mermaid">
 | 
			
		||||
      graph TB
 | 
			
		||||
        a_a(Aftonbladet) --> b_b[gorilla]:::apa --> c_c{chimp}:::apa -->a_a
 | 
			
		||||
        a_a --> c --> d_d --> c_c
 | 
			
		||||
        classDef apa fill:#f9f,stroke:#333,stroke-width:4px;
 | 
			
		||||
        class a_a apa;
 | 
			
		||||
        click a_a "http://www.aftonbladet.se" "apa"
 | 
			
		||||
    </div>
 | 
			
		||||
    <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        // themeCSS: '.node rect { fill: red; }',
 | 
			
		||||
        logLevel: 3,
 | 
			
		||||
        flowchart: { curve: 'linear' },
 | 
			
		||||
        gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorMargin: 50 },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
      });
 | 
			
		||||
    </script>
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@
 | 
			
		||||
        // arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        flowchart: { curve: 'linear', "htmlLabels": false },
 | 
			
		||||
        flowchart: { curve: 'linear', htmlLabels: false },
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorMargin: 50 },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,26 +1,26 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>info below</h1>
 | 
			
		||||
    <div class="mermaid">info</div>
 | 
			
		||||
    <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        // themeCSS: '.node rect { fill: red; }',
 | 
			
		||||
        logLevel: 3,
 | 
			
		||||
        flowchart: { curve: 'linear' },
 | 
			
		||||
        gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorMargin: 50 },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
      });
 | 
			
		||||
    </script>
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>info below</h1>
 | 
			
		||||
    <div class="mermaid">info</div>
 | 
			
		||||
    <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        // themeCSS: '.node rect { fill: red; }',
 | 
			
		||||
        logLevel: 3,
 | 
			
		||||
        flowchart: { curve: 'linear' },
 | 
			
		||||
        gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorMargin: 50 },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
      });
 | 
			
		||||
    </script>
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -90,31 +90,31 @@
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
  <script>
 | 
			
		||||
  function clickByFlow(elemName) {
 | 
			
		||||
    const div = document.createElement('div')
 | 
			
		||||
    div.className = 'created-by-click'
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;'
 | 
			
		||||
    div.innerText = 'Clicked By Flow'
 | 
			
		||||
    const div = document.createElement('div');
 | 
			
		||||
    div.className = 'created-by-click';
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;';
 | 
			
		||||
    div.innerText = 'Clicked By Flow';
 | 
			
		||||
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div)
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
  }
 | 
			
		||||
  function clickByGantt(arg1, arg2, arg3) {
 | 
			
		||||
    const div = document.createElement('div')
 | 
			
		||||
    div.className = 'created-by-gant-click'
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;'
 | 
			
		||||
    div.innerText = 'Clicked By Gant'
 | 
			
		||||
    const div = document.createElement('div');
 | 
			
		||||
    div.className = 'created-by-gant-click';
 | 
			
		||||
    div.style = 'padding: 20px; background: green; color: white;';
 | 
			
		||||
    div.innerText = 'Clicked By Gant';
 | 
			
		||||
    if (arg1) div.innerText += ' ' + arg1;
 | 
			
		||||
    if (arg2) div.innerText += ' ' + arg2;
 | 
			
		||||
    if (arg3) div.innerText += ' ' + arg3;
 | 
			
		||||
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div)
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
  }
 | 
			
		||||
  function clickByClass() {
 | 
			
		||||
    const div = document.createElement('div')
 | 
			
		||||
    div.className = 'created-by-class-click'
 | 
			
		||||
    div.style = 'padding: 20px; background: purple; color: white;'
 | 
			
		||||
    div.innerText = 'Clicked By Class'
 | 
			
		||||
    const div = document.createElement('div');
 | 
			
		||||
    div.className = 'created-by-class-click';
 | 
			
		||||
    div.style = 'padding: 20px; background: purple; color: white;';
 | 
			
		||||
    div.innerText = 'Clicked By Class';
 | 
			
		||||
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div)
 | 
			
		||||
    document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
  }
 | 
			
		||||
  mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 });
 | 
			
		||||
  </script>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										97
									
								
								cypress/platform/knsv2.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								cypress/platform/knsv2.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: false,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        securityLevel: 'strict',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
      var diagram = '%%{init: {"flowchart": {"htmlLabels": "false"}} }%%\n';
 | 
			
		||||
diagram += 'flowchart\n';
 | 
			
		||||
diagram += 'A["<ifra';
 | 
			
		||||
diagram += "me srcdoc='<scrip";
 | 
			
		||||
diagram += 't src=http://localhost:9000/exploit.js>';
 | 
			
		||||
diagram += '</scr';
 | 
			
		||||
diagram += 'ipt>\'></iframe>"]';
 | 
			
		||||
 | 
			
		||||
console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										212
									
								
								cypress/platform/knsv3.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								cypress/platform/knsv3.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,212 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>info below</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div class="mermaid2" style="width: 100%; height: 400px;">
 | 
			
		||||
%%{init: { "logLevel": 1, "er": {"fontSize":18 }} }%%
 | 
			
		||||
      erDiagram
 | 
			
		||||
        CUSTOMER }|..|{ DELIVERY-ADDRESS : has
 | 
			
		||||
        CUSTOMER ||--o{ ORDER : places
 | 
			
		||||
        CUSTOMER ||--o{ INVOICE : "liable for"
 | 
			
		||||
        DELIVERY-ADDRESS ||--o{ ORDER : receives
 | 
			
		||||
        INVOICE ||--|{ ORDER : covers
 | 
			
		||||
        ORDER ||--|{ ORDER-ITEM : includes
 | 
			
		||||
        PRODUCT-CATEGORY ||--|{ PRODUCT : contains
 | 
			
		||||
        PRODUCT ||--o{ ORDER-ITEM : "ordered in"
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="mermaid2" style="width: 50%; height: 400px;">
 | 
			
		||||
flowchart TD
 | 
			
		||||
  A[Christmas] ==> D
 | 
			
		||||
  A[Christmas] -->|Get money| B(Go shopping)
 | 
			
		||||
  A[Christmas] ==> C
 | 
			
		||||
  subgraph T ["Test"]
 | 
			
		||||
    A
 | 
			
		||||
    B
 | 
			
		||||
    C
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  classDef Test fill:#F84E68,stroke:#333,color:white;
 | 
			
		||||
  class A,T Test
 | 
			
		||||
  classDef TestSub fill:green;
 | 
			
		||||
  class T TestSub
 | 
			
		||||
  linkStyle 0,1 color:orange, stroke: orange;
 | 
			
		||||
</div>
 | 
			
		||||
      <div class="mermaid" style="width: 100%; height: 20%;">
 | 
			
		||||
flowchart TB
 | 
			
		||||
   subgraph S1
 | 
			
		||||
    sub1 -->sub2
 | 
			
		||||
   end
 | 
			
		||||
  subgraph S2
 | 
			
		||||
    sub4
 | 
			
		||||
   end
 | 
			
		||||
   S1 --> S2
 | 
			
		||||
   sub1 --> sub4
 | 
			
		||||
      </div>
 | 
			
		||||
<div class="mermaid2" style="width: 100%; height: 20%;">
 | 
			
		||||
flowchart TB
 | 
			
		||||
    c1-->a2
 | 
			
		||||
    subgraph one
 | 
			
		||||
    a1-->a2
 | 
			
		||||
    end
 | 
			
		||||
    subgraph two
 | 
			
		||||
    b1-->b2
 | 
			
		||||
    end
 | 
			
		||||
    subgraph three
 | 
			
		||||
    c1-->c2
 | 
			
		||||
    end
 | 
			
		||||
    one --> two
 | 
			
		||||
    three --> two
 | 
			
		||||
    two --> c2
 | 
			
		||||
</div>
 | 
			
		||||
      <div class="mermaid2" style="width: 100%; height: 20%;">
 | 
			
		||||
stateDiagram-v2
 | 
			
		||||
state S1 {
 | 
			
		||||
sub1 -->sub2
 | 
			
		||||
}
 | 
			
		||||
state S2 {
 | 
			
		||||
    sub4
 | 
			
		||||
}
 | 
			
		||||
S1 --> S2
 | 
			
		||||
sub1 --> sub4
 | 
			
		||||
 | 
			
		||||
      </div>
 | 
			
		||||
<div class="mermaid2" style="width: 100%; height: 20%;">
 | 
			
		||||
  requirementDiagram
 | 
			
		||||
  requirement test_req {
 | 
			
		||||
    id: 1
 | 
			
		||||
    text: the test text.
 | 
			
		||||
    risk: high
 | 
			
		||||
    verifymethod: test
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    functionalRequirement test_req2 {
 | 
			
		||||
    id: 1.1
 | 
			
		||||
    text: the second test text.
 | 
			
		||||
    risk: low
 | 
			
		||||
    verifymethod: inspection
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    performanceRequirement test_req3 {
 | 
			
		||||
    id: 1.2
 | 
			
		||||
    text: the third test text.
 | 
			
		||||
    risk: medium
 | 
			
		||||
    verifymethod: demonstration
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity {
 | 
			
		||||
    type: simulation
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity2 {
 | 
			
		||||
    type: word doc
 | 
			
		||||
    docRef: reqs/test_entity
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    test_entity - satisfies -> test_req2
 | 
			
		||||
    test_req - traces -> test_req2
 | 
			
		||||
    test_req - contains -> test_req3
 | 
			
		||||
    test_req <- copies - test_entity2
 | 
			
		||||
  </div>
 | 
			
		||||
      <div class="mermaid2" style="width: 50%; height: 20%;">
 | 
			
		||||
flowchart LR
 | 
			
		||||
  classDef dark fill:#000,stroke:#000,stroke-width:4px,color:#fff
 | 
			
		||||
  Lorem --> Ipsum --> Dolor
 | 
			
		||||
  class Lorem,Dolor dark
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="mermaid2" style="width: 50%; height: 20%;">
 | 
			
		||||
%%{init: {'theme': 'base' }}%%
 | 
			
		||||
%%{init2: { 'logLevel': 0, 'theme': 'forest'} }%%
 | 
			
		||||
flowchart TD
 | 
			
		||||
      L1 --- L2
 | 
			
		||||
      L2 --- C
 | 
			
		||||
      M1 ---> C
 | 
			
		||||
      R1 .-> R2
 | 
			
		||||
      R2 <.-> C
 | 
			
		||||
      C -->|Label 1| E1
 | 
			
		||||
      C <-- Label 2 ---> E2
 | 
			
		||||
      C ----> E3
 | 
			
		||||
      C <-...-> E4
 | 
			
		||||
      C ======> E5
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="mermaid2" style="width: 50%; height: 21%;">
 | 
			
		||||
flowchart LR
 | 
			
		||||
A[red text] -->|default style| B(blue text)
 | 
			
		||||
C([red text]) -->|default style| D[[blue text]]
 | 
			
		||||
E[(red text)] -->|default style| F((blue text))
 | 
			
		||||
G>red text] -->|default style| H{blue text}
 | 
			
		||||
I{{red text}} -->|default style| J[/blue text/]
 | 
			
		||||
K[
 | 
			
		||||
ed text] -->|default style| L[/blue text]
 | 
			
		||||
M[
 | 
			
		||||
ed text/] -->|default style| N[blue text]
 | 
			
		||||
linkStyle default color:Sienna;
 | 
			
		||||
style A stroke:#ff0000,fill:#ffcccc,color:#ff0000
 | 
			
		||||
style B stroke:#0000ff,fill:#ccccff,color:#0000ff
 | 
			
		||||
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
 | 
			
		||||
style D stroke:#0000ff,fill:#ccccff,color:#0000ff
 | 
			
		||||
style E stroke:#ff0000,fill:#ffcccc,color:#ff0000
 | 
			
		||||
style F stroke:#0000ff,fill:#ccccff,color:#0000ff
 | 
			
		||||
style G stroke:#ff0000,fill:#ffcccc,color:#ff0000
 | 
			
		||||
style H stroke:#0000ff,fill:#ccccff,color:#0000ff
 | 
			
		||||
style I stroke:#ff0000,fill:#ffcccc,color:#ff0000
 | 
			
		||||
style J stroke:#0000ff,fill:#ccccff,color:#0000ff
 | 
			
		||||
style K stroke:#ff0000,fill:#ffcccc,color:#ff0000
 | 
			
		||||
style L stroke:#0000ff,fill:#ccccff,color:#0000ff
 | 
			
		||||
style M stroke:#ff0000,fill:#ffcccc,color:#ff0000
 | 
			
		||||
style N stroke:#0000ff,fill:#ccccff,color:#0000ff
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'neutral',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        flowchart: { nodeSpacing: 10, curve: 'cardinal', htmlLabels: true },
 | 
			
		||||
        htmlLabels: true,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'cardinal',
 | 
			
		||||
        securityLevel: 'loose',
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										30
									
								
								cypress/platform/regression/issue-1874.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								cypress/platform/regression/issue-1874.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <script src="http://localhost:9000/mermaid.js"></script>
 | 
			
		||||
  <script>
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'base',
 | 
			
		||||
        themeVariables: {},
 | 
			
		||||
        startOnLoad: true,
 | 
			
		||||
      });
 | 
			
		||||
  </script>
 | 
			
		||||
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
  <h1>Example</h1>
 | 
			
		||||
  <div class="mermaid">
 | 
			
		||||
%%{init:{"theme":"base", "sequence": {"mirrorActors":false},"themeVariables": {"actorBkg":"red"}}}%%
 | 
			
		||||
sequenceDiagram
 | 
			
		||||
    Bert->>+Ernie: Start looking for the cookie!
 | 
			
		||||
    Ernie-->>-Bert: Found it!
 | 
			
		||||
    Note left of Ernie: Cookies are good
 | 
			
		||||
  </div>
 | 
			
		||||
  <div class="mermaid">
 | 
			
		||||
%%{init:{"theme":"base", "themeVariables": {}}}%%
 | 
			
		||||
sequenceDiagram
 | 
			
		||||
    Bert->>+Ernie: Start looking for the cookie!
 | 
			
		||||
    Ernie-->>-Bert: Found it!
 | 
			
		||||
    Note left of Ernie: Cookies are good
 | 
			
		||||
  </div>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -11,21 +11,16 @@
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <script src="./mermaid.js"></script>
 | 
			
		||||
        <script>
 | 
			
		||||
 | 
			
		||||
         mermaid.init({ startOnLoad: false });
 | 
			
		||||
        <script>mermaid.init({ startOnLoad: false });
 | 
			
		||||
         mermaid.mermaidAPI.initialize();
 | 
			
		||||
 | 
			
		||||
         try{
 | 
			
		||||
             mermaid.mermaidAPI.render("graphDiv",
 | 
			
		||||
                                       `>`);
 | 
			
		||||
         } catch(e){}
 | 
			
		||||
         try {
 | 
			
		||||
           mermaid.mermaidAPI.render('graphDiv', `>`);
 | 
			
		||||
         } catch (e) {}
 | 
			
		||||
 | 
			
		||||
         mermaid.mermaidAPI.render("graphDiv",
 | 
			
		||||
                                   `graph LR\n a --> b`, html => {
 | 
			
		||||
                                      document.getElementById('graph').innerHTML=html;
 | 
			
		||||
         mermaid.mermaidAPI.render('graphDiv', `graph LR\n a --> b`, (html) => {
 | 
			
		||||
           document.getElementById('graph').innerHTML = html;
 | 
			
		||||
         });
 | 
			
		||||
 | 
			
		||||
        </script>
 | 
			
		||||
 | 
			
		||||
    </body>
 | 
			
		||||
 
 | 
			
		||||
@@ -11,21 +11,18 @@
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
  <script>
 | 
			
		||||
 | 
			
		||||
    mermaid.init({ startOnLoad: false });
 | 
			
		||||
  <script>mermaid.init({ startOnLoad: false });
 | 
			
		||||
    mermaid.mermaidAPI.initialize();
 | 
			
		||||
 | 
			
		||||
    rerender('XMas');
 | 
			
		||||
 | 
			
		||||
    function rerender(text) {
 | 
			
		||||
      var graphText = `graph TD
 | 
			
		||||
        A[${text}] -->|Get money| B(Go shopping)`
 | 
			
		||||
        A[${text}] -->|Get money| B(Go shopping)`;
 | 
			
		||||
      var graph = mermaid.mermaidAPI.render('id', graphText);
 | 
			
		||||
      console.log('\x1b[35m%s\x1b[0m', '>> graph', graph)
 | 
			
		||||
      document.getElementById('graph').innerHTML=graph;
 | 
			
		||||
      console.log('\x1b[35m%s\x1b[0m', '>> graph', graph);
 | 
			
		||||
      document.getElementById('graph').innerHTML = graph;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  </script>
 | 
			
		||||
  <button id="rerender" onclick="rerender('Saturday')">Rerender</button>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -225,27 +225,67 @@ journey
 | 
			
		||||
              Go downstairs: 5: Me
 | 
			
		||||
              Sit down: 5: Me
 | 
			
		||||
      </div>
 | 
			
		||||
<div class="mermaid width height">
 | 
			
		||||
requirementDiagram
 | 
			
		||||
 | 
			
		||||
    requirement test_req {
 | 
			
		||||
    id: 1
 | 
			
		||||
    text: the test text.
 | 
			
		||||
    risk: high
 | 
			
		||||
    verifymethod: test
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    functionalRequirement test_req2 {
 | 
			
		||||
    id: 1.1
 | 
			
		||||
    text: the second test text.
 | 
			
		||||
    risk: low
 | 
			
		||||
    verifymethod: inspection
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    performanceRequirement test_req3 {
 | 
			
		||||
    id: 1.2
 | 
			
		||||
    text: the third test text.
 | 
			
		||||
    risk: medium
 | 
			
		||||
    verifymethod: demonstration
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity {
 | 
			
		||||
    type: simulation
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity2 {
 | 
			
		||||
    type: word doc
 | 
			
		||||
    docRef: reqs/test_entity
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    test_entity - satisfies -> test_req2
 | 
			
		||||
    test_req - traces -> test_req2
 | 
			
		||||
    test_req - contains -> test_req3
 | 
			
		||||
    test_req <- copies - test_entity2
 | 
			
		||||
      </div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
          // console.error('Mermaid error: ', err);
 | 
			
		||||
        };
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'base',
 | 
			
		||||
        // themeVariables:
 | 
			
		||||
        // arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        flowchart: { curve: 'cardinal', "htmlLabels": false },
 | 
			
		||||
        flowchart: { curve: 'cardinal', htmlLabels: false },
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorMargin: 50, showSequenceNumbers: true },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        fontFamily: '"arial", sans-serif',
 | 
			
		||||
        curve: 'cardinal',
 | 
			
		||||
        securityLevel: 'strict'
 | 
			
		||||
        securityLevel: 'strict',
 | 
			
		||||
      });
 | 
			
		||||
      function callback(){alert('It worked');}
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -219,19 +219,67 @@ journey
 | 
			
		||||
              Go downstairs: 5: Me
 | 
			
		||||
              Sit down: 5: Me
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="mermaid width height">
 | 
			
		||||
requirementDiagram
 | 
			
		||||
 | 
			
		||||
    requirement test_req {
 | 
			
		||||
    id: 1
 | 
			
		||||
    text: the test text.
 | 
			
		||||
    risk: high
 | 
			
		||||
    verifymethod: test
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    functionalRequirement test_req2 {
 | 
			
		||||
    id: 1.1
 | 
			
		||||
    text: the second test text.
 | 
			
		||||
    risk: low
 | 
			
		||||
    verifymethod: inspection
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    performanceRequirement test_req3 {
 | 
			
		||||
    id: 1.2
 | 
			
		||||
    text: the third test text.
 | 
			
		||||
    risk: medium
 | 
			
		||||
    verifymethod: demonstration
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity {
 | 
			
		||||
    type: simulation
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity2 {
 | 
			
		||||
    type: word doc
 | 
			
		||||
    docRef: reqs/test_entity
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    test_entity - satisfies -> test_req2
 | 
			
		||||
    test_req - traces -> test_req2
 | 
			
		||||
    test_req - contains -> test_req3
 | 
			
		||||
    test_req <- copies - test_entity2
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
          // console.error('Mermaid error: ', err);
 | 
			
		||||
        };
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'base',
 | 
			
		||||
        themeVariables: { primaryColor: '#9400D3', darkMode: true, background: '#222', textColor:'white', primaryTextColor: '#f4f4f4', nodeBkg: '#ff0000', mainBkg:'#0000ff', tertiaryColor:'#ffffcc' },
 | 
			
		||||
        themeVariables: {
 | 
			
		||||
    primaryColor: '#9400D3',
 | 
			
		||||
    darkMode: true,
 | 
			
		||||
    background: '#222',
 | 
			
		||||
    textColor: 'white',
 | 
			
		||||
    primaryTextColor: '#f4f4f4',
 | 
			
		||||
    nodeBkg: '#ff0000',
 | 
			
		||||
    mainBkg: '#0000ff',
 | 
			
		||||
    tertiaryColor: '#ffffcc',
 | 
			
		||||
  },
 | 
			
		||||
        // arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        flowchart: { curve: 'cardinal', "htmlLabels": false },
 | 
			
		||||
        flowchart: { curve: 'cardinal', htmlLabels: false },
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorMargin: 50, showSequenceNumbers: true },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
@@ -239,7 +287,9 @@ journey
 | 
			
		||||
        curve: 'cardinal',
 | 
			
		||||
        // securityLevel: 'strict'
 | 
			
		||||
      });
 | 
			
		||||
      function callback(){alert('It worked');}
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -217,26 +217,66 @@ gantt
 | 
			
		||||
              Go downstairs: 5: Me
 | 
			
		||||
              Sit down: 5: Me
 | 
			
		||||
      </div>
 | 
			
		||||
<div class="mermaid width height">
 | 
			
		||||
requirementDiagram
 | 
			
		||||
 | 
			
		||||
    requirement test_req {
 | 
			
		||||
    id: 1
 | 
			
		||||
    text: the test text.
 | 
			
		||||
    risk: high
 | 
			
		||||
    verifymethod: test
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    functionalRequirement test_req2 {
 | 
			
		||||
    id: 1.1
 | 
			
		||||
    text: the second test text.
 | 
			
		||||
    risk: low
 | 
			
		||||
    verifymethod: inspection
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    performanceRequirement test_req3 {
 | 
			
		||||
    id: 1.2
 | 
			
		||||
    text: the third test text.
 | 
			
		||||
    risk: medium
 | 
			
		||||
    verifymethod: demonstration
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity {
 | 
			
		||||
    type: simulation
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity2 {
 | 
			
		||||
    type: word doc
 | 
			
		||||
    docRef: reqs/test_entity
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    test_entity - satisfies -> test_req2
 | 
			
		||||
    test_req - traces -> test_req2
 | 
			
		||||
    test_req - contains -> test_req3
 | 
			
		||||
    test_req <- copies - test_entity2
 | 
			
		||||
      </div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
          // console.error('Mermaid error: ', err);
 | 
			
		||||
        };
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'dark',
 | 
			
		||||
        // arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        flowchart: { curve: 'cardinal', "htmlLabels": true },
 | 
			
		||||
        flowchart: { curve: 'cardinal', htmlLabels: true },
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorMargin: 50, showSequenceNumbers: true },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        fontFamily: '"arial", sans-serif',
 | 
			
		||||
        curve: 'cardinal',
 | 
			
		||||
        securityLevel: 'strict'
 | 
			
		||||
        securityLevel: 'strict',
 | 
			
		||||
      });
 | 
			
		||||
      function callback(){alert('It worked');}
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -212,26 +212,66 @@ gantt
 | 
			
		||||
              Go downstairs: 5: Me
 | 
			
		||||
              Sit down: 5: Me
 | 
			
		||||
      </div>
 | 
			
		||||
<div class="mermaid width height">
 | 
			
		||||
requirementDiagram
 | 
			
		||||
 | 
			
		||||
    requirement test_req {
 | 
			
		||||
    id: 1
 | 
			
		||||
    text: the test text.
 | 
			
		||||
    risk: high
 | 
			
		||||
    verifymethod: test
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    functionalRequirement test_req2 {
 | 
			
		||||
    id: 1.1
 | 
			
		||||
    text: the second test text.
 | 
			
		||||
    risk: low
 | 
			
		||||
    verifymethod: inspection
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    performanceRequirement test_req3 {
 | 
			
		||||
    id: 1.2
 | 
			
		||||
    text: the third test text.
 | 
			
		||||
    risk: medium
 | 
			
		||||
    verifymethod: demonstration
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity {
 | 
			
		||||
    type: simulation
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity2 {
 | 
			
		||||
    type: word doc
 | 
			
		||||
    docRef: reqs/test_entity
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    test_entity - satisfies -> test_req2
 | 
			
		||||
    test_req - traces -> test_req2
 | 
			
		||||
    test_req - contains -> test_req3
 | 
			
		||||
    test_req <- copies - test_entity2
 | 
			
		||||
      </div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
          // console.error('Mermaid error: ', err);
 | 
			
		||||
        };
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        // theme: 'dark',
 | 
			
		||||
        // arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        flowchart: { curve: 'cardinal', "htmlLabels": false },
 | 
			
		||||
        flowchart: { curve: 'cardinal', htmlLabels: false },
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorMargin: 50, showSequenceNumbers: true },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        fontFamily: '"arial", sans-serif',
 | 
			
		||||
        curve: 'cardinal',
 | 
			
		||||
        securityLevel: 'strict'
 | 
			
		||||
        securityLevel: 'strict',
 | 
			
		||||
      });
 | 
			
		||||
      function callback(){alert('It worked');}
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -216,26 +216,66 @@ gantt
 | 
			
		||||
              Go downstairs: 5: Me
 | 
			
		||||
              Sit down: 5: Me
 | 
			
		||||
      </div>
 | 
			
		||||
<div class="mermaid width height">
 | 
			
		||||
requirementDiagram
 | 
			
		||||
 | 
			
		||||
    requirement test_req {
 | 
			
		||||
    id: 1
 | 
			
		||||
    text: the test text.
 | 
			
		||||
    risk: high
 | 
			
		||||
    verifymethod: test
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    functionalRequirement test_req2 {
 | 
			
		||||
    id: 1.1
 | 
			
		||||
    text: the second test text.
 | 
			
		||||
    risk: low
 | 
			
		||||
    verifymethod: inspection
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    performanceRequirement test_req3 {
 | 
			
		||||
    id: 1.2
 | 
			
		||||
    text: the third test text.
 | 
			
		||||
    risk: medium
 | 
			
		||||
    verifymethod: demonstration
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity {
 | 
			
		||||
    type: simulation
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity2 {
 | 
			
		||||
    type: word doc
 | 
			
		||||
    docRef: reqs/test_entity
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    test_entity - satisfies -> test_req2
 | 
			
		||||
    test_req - traces -> test_req2
 | 
			
		||||
    test_req - contains -> test_req3
 | 
			
		||||
    test_req <- copies - test_entity2
 | 
			
		||||
      </div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
          // console.error('Mermaid error: ', err);
 | 
			
		||||
        };
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        // arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        flowchart: { curve: 'cardinal', "htmlLabels": false },
 | 
			
		||||
        flowchart: { curve: 'cardinal', htmlLabels: false },
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorMargin: 50, showSequenceNumbers: true },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        fontFamily: '"arial", sans-serif',
 | 
			
		||||
        curve: 'cardinal',
 | 
			
		||||
        securityLevel: 'strict'
 | 
			
		||||
        securityLevel: 'strict',
 | 
			
		||||
      });
 | 
			
		||||
      function callback(){alert('It worked');}
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -215,26 +215,66 @@ gantt
 | 
			
		||||
              Go downstairs: 5: Me
 | 
			
		||||
              Sit down: 5: Me
 | 
			
		||||
      </div>
 | 
			
		||||
<div class="mermaid width height">
 | 
			
		||||
requirementDiagram
 | 
			
		||||
 | 
			
		||||
    requirement test_req {
 | 
			
		||||
    id: 1
 | 
			
		||||
    text: the test text.
 | 
			
		||||
    risk: high
 | 
			
		||||
    verifymethod: test
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    functionalRequirement test_req2 {
 | 
			
		||||
    id: 1.1
 | 
			
		||||
    text: the second test text.
 | 
			
		||||
    risk: low
 | 
			
		||||
    verifymethod: inspection
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    performanceRequirement test_req3 {
 | 
			
		||||
    id: 1.2
 | 
			
		||||
    text: the third test text.
 | 
			
		||||
    risk: medium
 | 
			
		||||
    verifymethod: demonstration
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity {
 | 
			
		||||
    type: simulation
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element test_entity2 {
 | 
			
		||||
    type: word doc
 | 
			
		||||
    docRef: reqs/test_entity
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    test_entity - satisfies -> test_req2
 | 
			
		||||
    test_req - traces -> test_req2
 | 
			
		||||
    test_req - contains -> test_req3
 | 
			
		||||
    test_req <- copies - test_entity2
 | 
			
		||||
      </div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
          // console.error('Mermaid error: ', err);
 | 
			
		||||
        };
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'neutral',
 | 
			
		||||
        // arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        flowchart: { curve: 'cardinal', "htmlLabels": false },
 | 
			
		||||
        flowchart: { curve: 'cardinal', htmlLabels: false },
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorMargin: 50, showSequenceNumbers: true },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        fontFamily: '"arial", sans-serif',
 | 
			
		||||
        curve: 'cardinal',
 | 
			
		||||
        securityLevel: 'strict'
 | 
			
		||||
        securityLevel: 'strict',
 | 
			
		||||
      });
 | 
			
		||||
      function callback(){alert('It worked');}
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -37,9 +37,9 @@
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
  <script>
 | 
			
		||||
     function showFullFirstSquad(elemName) {
 | 
			
		||||
            console.log('show ' + elemName);
 | 
			
		||||
        }
 | 
			
		||||
        mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 });
 | 
			
		||||
       console.log('show ' + elemName);
 | 
			
		||||
     }
 | 
			
		||||
     mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 });
 | 
			
		||||
  </script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -120,8 +120,8 @@
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
          // console.error('Mermaid error: ', err);
 | 
			
		||||
        };
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        // theme: 'dark',
 | 
			
		||||
        // theme: 'dark',
 | 
			
		||||
@@ -129,7 +129,7 @@
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        // flowchart: { useMaxWidth: true },
 | 
			
		||||
        graph: { curve: 'cardinal', "htmlLabels": false },
 | 
			
		||||
        graph: { curve: 'cardinal', htmlLabels: false },
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorMargin: 50, showSequenceNumbers: true },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
@@ -137,7 +137,9 @@
 | 
			
		||||
        curve: 'cardinal',
 | 
			
		||||
        securityLevel: 'strict',
 | 
			
		||||
      });
 | 
			
		||||
      function callback(){alert('It worked');}
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,41 +1,41 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>User Journey</h1>
 | 
			
		||||
    <div class="mermaid">
 | 
			
		||||
      journey
 | 
			
		||||
        title Go shopping
 | 
			
		||||
 | 
			
		||||
        section Get to the shops
 | 
			
		||||
          Get car keys:5: Dad
 | 
			
		||||
          Get into car:5: Dad, Mum, Child 1, Child 2
 | 
			
		||||
          Really drive to supermarket:3: Dad
 | 
			
		||||
 | 
			
		||||
        section Do shopping
 | 
			
		||||
          Do actual shop:3: Mum
 | 
			
		||||
          Get in the way:2: Dad, Child 1, Child 2
 | 
			
		||||
          Pay: 2: Dad
 | 
			
		||||
 | 
			
		||||
        section Go home
 | 
			
		||||
          Lose keys:3: Dad
 | 
			
		||||
          Get cross:1: Dad, Child 1
 | 
			
		||||
          Find keys:4: Mum
 | 
			
		||||
          Get into car:4: Dad, Mum, Child 1, Child 2
 | 
			
		||||
          Drive home:3: Dad
 | 
			
		||||
    </div>
 | 
			
		||||
    <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        logLevel: 3,
 | 
			
		||||
        journey: { taskMargin: 30 },
 | 
			
		||||
      });
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>User Journey</h1>
 | 
			
		||||
    <div class="mermaid">
 | 
			
		||||
      journey
 | 
			
		||||
        title Go shopping
 | 
			
		||||
 | 
			
		||||
        section Get to the shops
 | 
			
		||||
          Get car keys:5: Dad
 | 
			
		||||
          Get into car:5: Dad, Mum, Child 1, Child 2
 | 
			
		||||
          Really drive to supermarket:3: Dad
 | 
			
		||||
 | 
			
		||||
        section Do shopping
 | 
			
		||||
          Do actual shop:3: Mum
 | 
			
		||||
          Get in the way:2: Dad, Child 1, Child 2
 | 
			
		||||
          Pay: 2: Dad
 | 
			
		||||
 | 
			
		||||
        section Go home
 | 
			
		||||
          Lose keys:3: Dad
 | 
			
		||||
          Get cross:1: Dad, Child 1
 | 
			
		||||
          Find keys:4: Mum
 | 
			
		||||
          Get into car:4: Dad, Mum, Child 1, Child 2
 | 
			
		||||
          Drive home:3: Dad
 | 
			
		||||
    </div>
 | 
			
		||||
    <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        logLevel: 3,
 | 
			
		||||
        journey: { taskMargin: 30 },
 | 
			
		||||
      });
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -29,9 +29,9 @@
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
  <script>
 | 
			
		||||
     function showFullFirstSquad(elemName) {
 | 
			
		||||
            console.log('show ' + elemName);
 | 
			
		||||
        }
 | 
			
		||||
        mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 });
 | 
			
		||||
       console.log('show ' + elemName);
 | 
			
		||||
     }
 | 
			
		||||
     mermaid.initialize({ startOnLoad: true, securityLevel: 'loose', logLevel: 1 });
 | 
			
		||||
  </script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -2,11 +2,10 @@ import { Base64 } from 'js-base64';
 | 
			
		||||
import mermaid2 from '../../src/mermaid';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ##contentLoaded
 | 
			
		||||
 * Callback function that is called when page is loaded. This functions fetches configuration for mermaid rendering and
 | 
			
		||||
 * calls init for rendering the mermaid diagrams on the page.
 | 
			
		||||
 * ##contentLoaded Callback function that is called when page is loaded. This functions fetches
 | 
			
		||||
 * configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the page.
 | 
			
		||||
 */
 | 
			
		||||
const contentLoaded = function() {
 | 
			
		||||
const contentLoaded = function () {
 | 
			
		||||
  let pos = document.location.href.indexOf('?graph=');
 | 
			
		||||
  if (pos > 0) {
 | 
			
		||||
    pos = pos + 7;
 | 
			
		||||
@@ -38,8 +37,12 @@ const contentLoaded = function() {
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param current
 | 
			
		||||
 * @param update
 | 
			
		||||
 */
 | 
			
		||||
function merge(current, update) {
 | 
			
		||||
  Object.keys(update).forEach(function(key) {
 | 
			
		||||
  Object.keys(update).forEach(function (key) {
 | 
			
		||||
    // if update[key] exist, and it's not a string or array,
 | 
			
		||||
    // we go in one level deeper
 | 
			
		||||
    if (
 | 
			
		||||
@@ -58,7 +61,7 @@ function merge(current, update) {
 | 
			
		||||
  return current;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const contentLoadedApi = function() {
 | 
			
		||||
const contentLoadedApi = function () {
 | 
			
		||||
  let pos = document.location.href.indexOf('?graph=');
 | 
			
		||||
  if (pos > 0) {
 | 
			
		||||
    pos = pos + 7;
 | 
			
		||||
@@ -125,7 +128,7 @@ if (typeof document !== 'undefined') {
 | 
			
		||||
   */
 | 
			
		||||
  window.addEventListener(
 | 
			
		||||
    'load',
 | 
			
		||||
    function() {
 | 
			
		||||
    function () {
 | 
			
		||||
      if (this.location.href.match('xss.html')) {
 | 
			
		||||
        this.console.log('Using api');
 | 
			
		||||
        contentLoadedApi();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +1,18 @@
 | 
			
		||||
<!doctype html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
  <style>
 | 
			
		||||
  /* .mermaid {
 | 
			
		||||
    font-family: "trebuchet ms", verdana, arial;;
 | 
			
		||||
  } */
 | 
			
		||||
  /* .mermaid {
 | 
			
		||||
    font-family: 'arial';
 | 
			
		||||
  } */
 | 
			
		||||
  </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
  <div id="graph-to-be"></div>
 | 
			
		||||
  <script src="./bundle-test.js" charset="utf-8"></script>
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
<!doctype html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
  <style>
 | 
			
		||||
  /* .mermaid {
 | 
			
		||||
    font-family: "trebuchet ms", verdana, arial;;
 | 
			
		||||
  } */
 | 
			
		||||
  /* .mermaid {
 | 
			
		||||
    font-family: 'arial';
 | 
			
		||||
  } */
 | 
			
		||||
  </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
  <div id="graph-to-be"></div>
 | 
			
		||||
  <script src="./bundle-test.js" charset="utf-8"></script>
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
@@ -23,11 +23,11 @@
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
    <script>
 | 
			
		||||
      function xssAttack(){
 | 
			
		||||
        const div = document.createElement('div')
 | 
			
		||||
        div.id = 'the-malware'
 | 
			
		||||
        div.className = 'malware'
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded'
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        // const el = document.querySelector('.mermaid');
 | 
			
		||||
        // el.parentNode.removeChild(el);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										108
									
								
								cypress/platform/xss10.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								cypress/platform/xss10.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-d3',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: true,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        securityLevel: 'antiscript',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var diagram = 'classDiagram\n';
 | 
			
		||||
diagram += 'class Square~<img/src';
 | 
			
		||||
diagram += "='1'/onerror=xssAttack()>~{\n";
 | 
			
		||||
diagram += 'id A\n';
 | 
			
		||||
diagram += '}';
 | 
			
		||||
 | 
			
		||||
//   var diagram = "stateDiagram-v2\n";
 | 
			
		||||
//  diagram += "<img/src='1'/onerror"
 | 
			
		||||
//  diagram += "=xssAttack()> --> B";
 | 
			
		||||
console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  console.log(res);
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										106
									
								
								cypress/platform/xss11.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								cypress/platform/xss11.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-d3',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: true,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        securityLevel: 'antiscript',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
var diagram = 'stateDiagram-v2\n';
 | 
			
		||||
diagram += 's2 : This is a state description<img/src';
 | 
			
		||||
diagram += "='1'/onerror=xssAttack()>";
 | 
			
		||||
 | 
			
		||||
//   var diagram = "stateDiagram-v2\n";
 | 
			
		||||
//  diagram += "<img/src='1'/onerror"
 | 
			
		||||
//  diagram += "=xssAttack()> --> B";
 | 
			
		||||
console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  console.log(res);
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										106
									
								
								cypress/platform/xss12.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								cypress/platform/xss12.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-d3',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: true,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        securityLevel: 'antiscript',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
var diagram = 'stateDiagram-v2\n';
 | 
			
		||||
diagram += 's2 : A<img/src';
 | 
			
		||||
diagram += "='1'/onerror=xssAttack()>";
 | 
			
		||||
 | 
			
		||||
//   var diagram = "stateDiagram-v2\n";
 | 
			
		||||
//  diagram += "<img/src='1'/onerror"
 | 
			
		||||
//  diagram += "=xssAttack()> --> B";
 | 
			
		||||
console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  console.log(res);
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										106
									
								
								cypress/platform/xss13.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								cypress/platform/xss13.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-d3',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: true,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        securityLevel: 'antiscript',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
var diagram = 'stateDiagram-v2\n';
 | 
			
		||||
diagram += 'if_state --> False: if n < 0<img/src';
 | 
			
		||||
diagram += "='1'/onerror=xssAttack()>";
 | 
			
		||||
 | 
			
		||||
//   var diagram = "stateDiagram-v2\n";
 | 
			
		||||
//  diagram += "<img/src='1'/onerror"
 | 
			
		||||
//  diagram += "=xssAttack()> --> B";
 | 
			
		||||
console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  console.log(res);
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										108
									
								
								cypress/platform/xss14.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								cypress/platform/xss14.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-d3',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: true,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        securityLevel: 'antiscript',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var diagram = 'classDiagram\n';
 | 
			
		||||
diagram += 'classA <-- classB : <ifr';
 | 
			
		||||
diagram += "ame/srcdoc='<scr";
 | 
			
		||||
diagram += 'ipt>parent.xssAttack(`XSS`)</';
 | 
			
		||||
diagram += "script>'>";
 | 
			
		||||
 | 
			
		||||
//   var diagram = "stateDiagram-v2\n";
 | 
			
		||||
//  diagram += "<img/src='1'/onerror"
 | 
			
		||||
//  diagram += "=xssAttack()> --> B";
 | 
			
		||||
console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  console.log(res);
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										107
									
								
								cypress/platform/xss15.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								cypress/platform/xss15.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-d3',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: true,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        securityLevel: 'strict',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var diagram = `sequenceDiagram
 | 
			
		||||
    participant John
 | 
			
		||||
    links John: {"XSS": "javas`;
 | 
			
		||||
diagram += `cript:alert('AudioParam')"}`;
 | 
			
		||||
 | 
			
		||||
//   var diagram = "stateDiagram-v2\n";
 | 
			
		||||
//  diagram += "<img/src='1'/onerror"
 | 
			
		||||
//  diagram += "=xssAttack()> --> B";
 | 
			
		||||
console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  console.log(res);
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										106
									
								
								cypress/platform/xss16.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								cypress/platform/xss16.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-d3',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: true,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        securityLevel: 'loose',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var diagram = `sequenceDiagram
 | 
			
		||||
    participant Alice
 | 
			
		||||
    links Alice: { "Click me!" : "javasjavascript:cript:alert('goose')" }`;
 | 
			
		||||
 | 
			
		||||
// //   var diagram = "stateDiagram-v2\n";
 | 
			
		||||
// //  diagram += "<img/src='1'/onerror"
 | 
			
		||||
// diagram += '//via.placeholder.com/64\' width=64 />"]';
 | 
			
		||||
// console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  console.log(res);
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										106
									
								
								cypress/platform/xss17.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								cypress/platform/xss17.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-d3',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: true,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        securityLevel: 'loose',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var diagram = `sequenceDiagram
 | 
			
		||||
    participant Alice
 | 
			
		||||
    link Alice: Click Me!@javasjavascript:cript:alert("goose")`;
 | 
			
		||||
 | 
			
		||||
// //   var diagram = "stateDiagram-v2\n";
 | 
			
		||||
// //  diagram += "<img/src='1'/onerror"
 | 
			
		||||
// diagram += '//via.placeholder.com/64\' width=64 />"]';
 | 
			
		||||
// console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  console.log(res);
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										105
									
								
								cypress/platform/xss18.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								cypress/platform/xss18.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-d3',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: true,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        // securityLevel: 'loose',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var diagram = `classDiagram
 | 
			
		||||
      Class "<img/src='x'/onerror=xssAttack(1)>" <--> "<img/src='x'/onerror=xssAttack(2)>" C2: Cool label`;
 | 
			
		||||
 | 
			
		||||
// //   var diagram = "stateDiagram-v2\n";
 | 
			
		||||
// //  diagram += "<img/src='1'/onerror"
 | 
			
		||||
// diagram += '//via.placeholder.com/64\' width=64 />"]';
 | 
			
		||||
// console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  console.log(res);
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										107
									
								
								cypress/platform/xss19.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								cypress/platform/xss19.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-d3',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: true,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        // securityLevel: 'loose',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var diagram = `classDiagram
 | 
			
		||||
class Shape{
 | 
			
		||||
    <<<img/src='1'/`;
 | 
			
		||||
 | 
			
		||||
// //   var diagram = "stateDiagram-v2\n";
 | 
			
		||||
diagram += `onerror=xssAttack()>>>
 | 
			
		||||
}`;
 | 
			
		||||
// diagram += '//via.placeholder.com/64\' width=64 />"]';
 | 
			
		||||
// console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  console.log(res);
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										75
									
								
								cypress/platform/xss2.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								cypress/platform/xss2.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <style>
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
    <script>
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
    </script>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div class="mermaid">
 | 
			
		||||
      %%{init: { 'theme':'base', '__proto__': {'polluted': 'asdf'}} }%%
 | 
			
		||||
      graph LR
 | 
			
		||||
          A --> B
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="mermaid">
 | 
			
		||||
      %%{init: { 'theme':'base', '__proto__': {'polluted': 'asdf'}} }%%
 | 
			
		||||
      %%{init: { 'theme':'base', '__proto__': {'polluted': 'asdf'}} }%%
 | 
			
		||||
      graph LR
 | 
			
		||||
          A --> B
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="mermaid">
 | 
			
		||||
      %%{init: { 'prototype': {'__proto__': {'polluted': 'test'}}} }%%
 | 
			
		||||
      %%{init: { 'prototype': {'__proto__': {'polluted': 'test'}}} }%%
 | 
			
		||||
      sequenceDiagram
 | 
			
		||||
      Alice->>Bob: Hi Bob
 | 
			
		||||
      Bob->>Alice: Hi Alice
 | 
			
		||||
    </div>
 | 
			
		||||
    <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        startOnLoad: true,
 | 
			
		||||
        useMaxWidth: true,
 | 
			
		||||
      });
 | 
			
		||||
      var cnt = 0;
 | 
			
		||||
      var a;
 | 
			
		||||
      var handler = setInterval(() => {
 | 
			
		||||
        cnt++;
 | 
			
		||||
        a = {};
 | 
			
		||||
        if (typeof a.polluted !== 'undefined') {
 | 
			
		||||
          clearInterval(handler);
 | 
			
		||||
          xssAttack();
 | 
			
		||||
        }
 | 
			
		||||
        if (cnt > 20) {
 | 
			
		||||
          clearInterval(handler);
 | 
			
		||||
        }
 | 
			
		||||
      }, 100);
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										62
									
								
								cypress/platform/xss3.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								cypress/platform/xss3.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <style>
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
    <script>
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
    </script>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div class="mermaid">
 | 
			
		||||
      %%{init: { 'fontFamily': '\"></style><img src=x onerror=xssAttack()>'} }%%
 | 
			
		||||
      graph LR
 | 
			
		||||
          A --> B
 | 
			
		||||
    </div>
 | 
			
		||||
    <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        startOnLoad: true,
 | 
			
		||||
        useMaxWidth: true,
 | 
			
		||||
      });
 | 
			
		||||
      var cnt = 0;
 | 
			
		||||
      var a;
 | 
			
		||||
      var handler = setInterval(() => {
 | 
			
		||||
        cnt++;
 | 
			
		||||
        a = {};
 | 
			
		||||
        if (typeof a.polluted !== 'undefined') {
 | 
			
		||||
          clearInterval(handler);
 | 
			
		||||
          xssAttack();
 | 
			
		||||
        }
 | 
			
		||||
        if (cnt > 20) {
 | 
			
		||||
          clearInterval(handler);
 | 
			
		||||
        }
 | 
			
		||||
      }, 100);
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										98
									
								
								cypress/platform/xss4.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								cypress/platform/xss4.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: false,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        securityLevel: 'strict',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
      var diagram = '%%{init: {"flowchart": {"htmlLabels": "true"}} }%%\n';
 | 
			
		||||
diagram += 'flowchart\n';
 | 
			
		||||
diagram += 'A["<ifra';
 | 
			
		||||
diagram += "me srcdoc='<scrip";
 | 
			
		||||
diagram += 't src=http://localhost:9000/exploit.js>';
 | 
			
		||||
diagram += '</scr';
 | 
			
		||||
diagram += 'ipt>\'></iframe>"]';
 | 
			
		||||
 | 
			
		||||
console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										103
									
								
								cypress/platform/xss5.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								cypress/platform/xss5.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: true,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        securityLevel: 'antiscript',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
      var diagram = 'graph LR\n';
 | 
			
		||||
diagram += 'B-->D("<img onerror=location=`java';
 | 
			
		||||
// diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n";
 | 
			
		||||
diagram += 'script\x3a;xssAttack\u0028\u0029` src=x>");\n';
 | 
			
		||||
 | 
			
		||||
console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  console.log(res);
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										101
									
								
								cypress/platform/xss6.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								cypress/platform/xss6.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,101 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: true,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        securityLevel: 'antiscript',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
      var diagram = 'graph LR\n';
 | 
			
		||||
diagram += 'A(<img/src/onerror=xssAttack`1`>)';
 | 
			
		||||
// diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n";
 | 
			
		||||
console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  console.log(res);
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										103
									
								
								cypress/platform/xss7.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								cypress/platform/xss7.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-d3',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: true,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        securityLevel: 'antiscript',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
      var diagram = 'graph LR\n';
 | 
			
		||||
diagram += " B(<a href='<";
 | 
			
		||||
diagram += 'script></';
 | 
			
		||||
diagram += "script>Javascript:xssAttack`1`'>Click)";
 | 
			
		||||
// diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n";
 | 
			
		||||
console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  console.log(res);
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										102
									
								
								cypress/platform/xss8.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								cypress/platform/xss8.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: true,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        securityLevel: 'antiscript',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
var diagram = 'stateDiagram-v2\n';
 | 
			
		||||
diagram += "<img/src='1'/onerror=xssAttack()> --> B";
 | 
			
		||||
// diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n";
 | 
			
		||||
console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  console.log(res);
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										102
									
								
								cypress/platform/xss9.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								cypress/platform/xss9.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <link
 | 
			
		||||
      href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
 | 
			
		||||
      rel="stylesheet"
 | 
			
		||||
    />
 | 
			
		||||
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
 | 
			
		||||
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        /* background: rgb(221, 208, 208); */
 | 
			
		||||
        /* background:#333; */
 | 
			
		||||
        font-family: 'Arial';
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
        }
 | 
			
		||||
      h1 { color: grey;}
 | 
			
		||||
      .mermaid2 {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
      .mermaid svg {
 | 
			
		||||
        /* font-size: 18px !important; */
 | 
			
		||||
      }
 | 
			
		||||
      .malware {
 | 
			
		||||
        position: fixed;
 | 
			
		||||
        bottom:0;
 | 
			
		||||
        left:0;
 | 
			
		||||
        right:0;
 | 
			
		||||
        height: 150px;
 | 
			
		||||
        background: red;
 | 
			
		||||
        color: black;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        justify-content: center;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        font-family: monospace;
 | 
			
		||||
        font-size: 72px;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div>Security check</div>
 | 
			
		||||
    <div class="flex">
 | 
			
		||||
      <div id="diagram" class="mermaid"></div>
 | 
			
		||||
      <div id="res" class=""></div>
 | 
			
		||||
  <script src="./mermaid.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      mermaid.parseError = function (err, hash) {
 | 
			
		||||
        // console.error('Mermaid error: ', err);
 | 
			
		||||
      };
 | 
			
		||||
      mermaid.initialize({
 | 
			
		||||
        theme: 'forest',
 | 
			
		||||
        arrowMarkerAbsolute: true,
 | 
			
		||||
        // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}',
 | 
			
		||||
        logLevel: 0,
 | 
			
		||||
        state: {
 | 
			
		||||
          defaultRenderer: 'dagre-d3',
 | 
			
		||||
        },
 | 
			
		||||
        flowchart: {
 | 
			
		||||
          // defaultRenderer: 'dagre-wrapper',
 | 
			
		||||
          nodeSpacing: 10,
 | 
			
		||||
    curve: 'cardinal',
 | 
			
		||||
    htmlLabels: true,
 | 
			
		||||
        },
 | 
			
		||||
        htmlLabels: true,
 | 
			
		||||
        // gantt: { axisFormat: '%m/%d/%Y' },
 | 
			
		||||
        sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false },
 | 
			
		||||
        // sequenceDiagram: { actorMargin: 300 } // deprecated
 | 
			
		||||
        // fontFamily: '"times", sans-serif',
 | 
			
		||||
        // fontFamily: 'courier',
 | 
			
		||||
        fontSize: 18,
 | 
			
		||||
        curve: 'basis',
 | 
			
		||||
        securityLevel: 'antiscript',
 | 
			
		||||
        startOnLoad: false,
 | 
			
		||||
        secure: ['secure', 'securityLevel', 'startOnLoad', 'maxTextSize'],
 | 
			
		||||
        // themeVariables: {relationLabelColor: 'red'}
 | 
			
		||||
      });
 | 
			
		||||
      function callback() {
 | 
			
		||||
  alert('It worked');
 | 
			
		||||
}
 | 
			
		||||
      function xssAttack() {
 | 
			
		||||
        const div = document.createElement('div');
 | 
			
		||||
        div.id = 'the-malware';
 | 
			
		||||
        div.className = 'malware';
 | 
			
		||||
        div.innerHTML = 'XSS Succeeded';
 | 
			
		||||
        document.getElementsByTagName('body')[0].appendChild(div);
 | 
			
		||||
        throw new Error('XSS Succeded');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
var diagram = 'stateDiagram-v2\n';
 | 
			
		||||
diagram += "<img/src='1'/onerror=xssAttack()> --> B";
 | 
			
		||||
// diagram += "script\u003aalert\u0028document.domain\u0029\` src=x>\"\);\n";
 | 
			
		||||
console.log(diagram);
 | 
			
		||||
// document.querySelector('#diagram').innerHTML = diagram;
 | 
			
		||||
mermaid.render('diagram', diagram, (res) => {
 | 
			
		||||
  console.log(res);
 | 
			
		||||
  document.querySelector('#res').innerHTML = res;
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
@@ -16,10 +16,7 @@
 | 
			
		||||
//   // `config` is the resolved Cypress config
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
let percyHealthCheck = require("@percy/cypress/task");
 | 
			
		||||
 | 
			
		||||
module.exports = (on, config) => {
 | 
			
		||||
  // `on` is used to hook into various events Cypress emits
 | 
			
		||||
  // `config` is the resolved Cypress config
 | 
			
		||||
  on("task", percyHealthCheck);
 | 
			
		||||
};
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -24,4 +24,4 @@
 | 
			
		||||
// -- This is will overwrite an existing command --
 | 
			
		||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
 | 
			
		||||
 | 
			
		||||
import '@percy/cypress'
 | 
			
		||||
import '@percy/cypress';
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,8 @@
 | 
			
		||||
// ***********************************************************
 | 
			
		||||
 | 
			
		||||
// Import commands.js using ES2015 syntax:
 | 
			
		||||
import './commands'
 | 
			
		||||
import './commands';
 | 
			
		||||
import '@percy/cypress';
 | 
			
		||||
 | 
			
		||||
// Alternatively you can use CommonJS syntax:
 | 
			
		||||
// require('./commands')
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user