cleanup(graph): add e2e tests to task graph (#13342)

This commit is contained in:
Philip Fulcher 2022-11-22 20:04:41 -07:00 committed by GitHub
parent a243e809ba
commit cb2d6b61dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 2449 additions and 240 deletions

View File

@ -9,7 +9,7 @@ const cypressJsonConfig = {
videosFolder: '../../dist/cypress/graph/client-e2e/videos',
screenshotsFolder: '../../dist/cypress/graph/client-e2e/screenshots',
chromeWebSecurity: false,
specPattern: './src/release-static-integration/**/*.cy.{js,jsx,ts,tsx}',
specPattern: './src/e2e/**/release-static*.cy.{js,jsx,ts,tsx}',
supportFile: 'src/support/e2e.ts',
};
export default defineConfig({

View File

@ -9,7 +9,7 @@ const cypressJsonConfig = {
videosFolder: '../../dist/cypress/graph/client-e2e/videos',
screenshotsFolder: '../../dist/cypress/graph/client-e2e/screenshots',
chromeWebSecurity: false,
specPattern: './src/release-integration/**/*.cy.{js,jsx,ts,tsx}',
specPattern: './src/e2e/**/release-serve-*.cy.{js,jsx,ts,tsx}',
supportFile: 'src/support/e2e.ts',
};
export default defineConfig({

View File

@ -9,7 +9,7 @@ const cypressJsonConfig = {
videosFolder: '../../dist/cypress/graph/client-e2e/videos',
screenshotsFolder: '../../dist/cypress/graph/client-e2e/screenshots',
chromeWebSecurity: false,
specPattern: './src/watch-mode-integration/**/*.cy.{js,jsx,ts,tsx}',
specPattern: './src/e2e/**/watch-mode-*.cy.{js,jsx,ts,tsx}',
supportFile: 'src/support/e2e.ts',
};
export default defineConfig({

View File

@ -9,7 +9,7 @@ const cypressJsonConfig = {
videosFolder: '../../dist/cypress/graph/client-e2e/videos',
screenshotsFolder: '../../dist/cypress/graph/client-e2e/screenshots',
chromeWebSecurity: false,
specPattern: 'src/e2e/**/*.cy.{js,jsx,ts,tsx}',
specPattern: 'src/e2e/**/dev-*.cy.{js,jsx,ts,tsx}',
supportFile: 'src/support/e2e.ts',
};
export default defineConfig({

View File

@ -0,0 +1,125 @@
import {
getCheckedProjectItems,
getDeselectAllButton,
getFocusButtonForProject,
getGroupByFolderCheckbox,
getImageDownloadButton,
getIncludeProjectsInPathButton,
getSearchDepthCheckbox,
getSearchDepthIncrementButton,
getSelectAffectedButton,
getSelectAllButton,
getSelectProjectsMessage,
getTextFilterInput,
getTextFilterReset,
getToggleAllButtonForFolder,
getUncheckedProjectItems,
getUnfocusProjectButton,
} from '../support/app.po';
import * as affectedJson from '../fixtures/affected.json';
import { testProjectsRoutes } from '../support/routing-tests';
import * as nxExamplesJson from '../fixtures/nx-examples-project-graph.json';
describe('dev mode - app', () => {
before(() => {
cy.intercept('/assets/project-graphs/e2e.json', {
fixture: 'nx-examples-project-graph.json',
}).as('getGraph');
cy.visit('/');
// wait for initial graph to finish loading
cy.wait('@getGraph');
});
describe('theme preferences', () => {
let systemTheme: string;
before(() => {
cy.visit('/');
systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light';
});
it('should initialize localstorage with default theme', () => {
expect(localStorage.getItem('nx-dep-graph-theme')).eq('system');
});
it('has system default theme', () => {
cy.log('system theme is:', systemTheme);
cy.get('html').should('have.class', systemTheme);
});
describe('dark theme is set as prefered', () => {
before(() => {
cy.get('[data-cy="theme-open-modal-button"]').click();
cy.get('[data-cy="dark-theme-button"]').click();
});
it('should set dark theme', () => {
cy.log('Localstorage is: ', localStorage.getItem('nx-dep-graph-theme'));
expect(localStorage.getItem('nx-dep-graph-theme')).eq('dark');
cy.get('html').should('have.class', 'dark');
});
});
describe('light theme is set as preferred', () => {
before(() => {
cy.get('[data-cy="theme-open-modal-button"]').click();
cy.get('[data-cy="light-theme-button"]').click();
});
it('should set light theme', () => {
cy.log('Localstorage is: ', localStorage.getItem('nx-dep-graph-theme'));
expect(localStorage.getItem('nx-dep-graph-theme')).eq('light');
cy.get('html').should('have.class', 'light');
});
});
});
describe('graph layout direction preferences', () => {
let rankDir: string;
before(() => {
cy.visit('/');
rankDir = 'TB';
});
it('should initialize localstorage with default graph layout direction', () => {
expect(localStorage.getItem('nx-dep-graph-rankdir')).eq(rankDir);
});
describe('left-to-right graph layout direction is set as preferred', () => {
before(() => {
cy.get('[data-cy="lr-rankdir-button"]').click();
});
it('should set left-to-right graph layout direction', () => {
cy.log(
'Localstorage is: ',
localStorage.getItem('nx-dep-graph-rankdir')
);
expect(localStorage.getItem('nx-dep-graph-rankdir')).eq('LR');
cy.get('[data-cy="tb-rankdir-button"]').should(
(elem) => expect(elem).to.exist
);
});
});
describe('top-to-bottom graph layout direction is set as preferred', () => {
before(() => {
cy.get('[data-cy="tb-rankdir-button"]').click();
});
it('should set top-to-bottom graph layout direction', () => {
cy.log(
'Localstorage is: ',
localStorage.getItem('nx-dep-graph-rankdir')
);
expect(localStorage.getItem('nx-dep-graph-rankdir')).eq('TB');
cy.get('[data-cy="lr-rankdir-button"]').should(
(elem) => expect(elem).to.exist
);
});
});
});
});

View File

@ -19,12 +19,12 @@ import {
import * as affectedJson from '../fixtures/affected.json';
import { testProjectsRoutes } from '../support/routing-tests';
import * as nxExamplesJson from '../fixtures/nx-examples.json';
import * as nxExamplesJson from '../fixtures/nx-examples-project-graph.json';
describe('graph-client', () => {
describe('dev mode - project graph', () => {
before(() => {
cy.intercept('/assets/project-graphs/e2e.json', {
fixture: 'nx-examples.json',
fixture: 'nx-examples-project-graph.json',
}).as('getGraph');
cy.visit('/');
@ -156,7 +156,7 @@ describe('graph-client', () => {
// switch back to Nx Examples graph before proceeding
cy.intercept('/assets/project-graphs/e2e.json', {
fixture: 'nx-examples.json',
fixture: 'nx-examples-project-graph.json',
}).as('getGraph');
cy.get('[data-cy=project-select]').select('e2e', { force: true });
cy.wait('@getGraph');
@ -309,7 +309,7 @@ describe('graph-client', () => {
describe('loading graph client with url params', () => {
beforeEach(() => {
cy.intercept('/assets/project-graphs/*', {
fixture: 'nx-examples.json',
fixture: 'nx-examples-project-graph.json',
}).as('getGraph');
});
@ -317,88 +317,3 @@ describe('loading graph client with url params', () => {
// and also new /projects route
testProjectsRoutes('browser', ['/', '/e2e/projects']);
});
describe('theme preferences', () => {
let systemTheme: string;
before(() => {
cy.visit('/');
systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light';
});
it('should initialize localstorage with default theme', () => {
expect(localStorage.getItem('nx-dep-graph-theme')).eq('system');
});
it('has system default theme', () => {
cy.log('system theme is:', systemTheme);
cy.get('html').should('have.class', systemTheme);
});
describe('dark theme is set as prefered', () => {
before(() => {
cy.get('[data-cy="theme-open-modal-button"]').click();
cy.get('[data-cy="dark-theme-button"]').click();
});
it('should set dark theme', () => {
cy.log('Localstorage is: ', localStorage.getItem('nx-dep-graph-theme'));
expect(localStorage.getItem('nx-dep-graph-theme')).eq('dark');
cy.get('html').should('have.class', 'dark');
});
});
describe('light theme is set as preferred', () => {
before(() => {
cy.get('[data-cy="theme-open-modal-button"]').click();
cy.get('[data-cy="light-theme-button"]').click();
});
it('should set light theme', () => {
cy.log('Localstorage is: ', localStorage.getItem('nx-dep-graph-theme'));
expect(localStorage.getItem('nx-dep-graph-theme')).eq('light');
cy.get('html').should('have.class', 'light');
});
});
});
describe('graph layout direction preferences', () => {
let rankDir: string;
before(() => {
cy.visit('/');
rankDir = 'TB';
});
it('should initialize localstorage with default graph layout direction', () => {
expect(localStorage.getItem('nx-dep-graph-rankdir')).eq(rankDir);
});
describe('left-to-right graph layout direction is set as preferred', () => {
before(() => {
cy.get('[data-cy="lr-rankdir-button"]').click();
});
it('should set left-to-right graph layout direction', () => {
cy.log('Localstorage is: ', localStorage.getItem('nx-dep-graph-rankdir'));
expect(localStorage.getItem('nx-dep-graph-rankdir')).eq('LR');
cy.get('[data-cy="tb-rankdir-button"]').should(
(elem) => expect(elem).to.exist
);
});
});
describe('top-to-bottom graph layout direction is set as preferred', () => {
before(() => {
cy.get('[data-cy="tb-rankdir-button"]').click();
});
it('should set top-to-bottom graph layout direction', () => {
cy.log('Localstorage is: ', localStorage.getItem('nx-dep-graph-rankdir'));
expect(localStorage.getItem('nx-dep-graph-rankdir')).eq('TB');
cy.get('[data-cy="lr-rankdir-button"]').should(
(elem) => expect(elem).to.exist
);
});
});
});

View File

@ -0,0 +1,164 @@
import {
getCheckedProjectItems,
getDeselectAllButton,
getFocusButtonForProject,
getGroupByFolderCheckbox,
getGroupByProjectCheckbox,
getImageDownloadButton,
getIncludeProjectsInPathButton,
getSearchDepthCheckbox,
getSearchDepthIncrementButton,
getSelectAffectedButton,
getSelectAllButton,
getSelectProjectsMessage,
getSelectTargetDropdown,
getSelectTasksMessage,
getTextFilterInput,
getTextFilterReset,
getToggleAllButtonForFolder,
getUncheckedProjectItems,
getUnfocusProjectButton,
} from '../support/app.po';
import * as affectedJson from '../fixtures/affected.json';
import { testProjectsRoutes, testTaskRoutes } from '../support/routing-tests';
import * as nxExamplesJson from '../fixtures/nx-examples-project-graph.json';
describe('dev mode - task graph', () => {
before(() => {
cy.intercept('/assets/project-graphs/e2e.json', {
fixture: 'nx-examples-project-graph.json',
}).as('getGraph');
cy.intercept('/assets/task-graphs/e2e.json', {
fixture: 'nx-examples-task-graphs.json',
}).as('getTaskGraph');
cy.visit('/e2e/tasks');
// wait for initial graphs to finish loading
cy.wait('@getGraph');
cy.wait('@getTaskGraph');
});
afterEach(() => {
// clean up by hiding all tasks
getDeselectAllButton().click();
getCheckedProjectItems().should('have.length', 0);
});
describe('select tasks message', () => {
it('should display on load', () => {
getSelectTasksMessage().should('be.visible');
});
it('should hide when a project is selected', () => {
cy.contains('cart').scrollIntoView().should('be.visible');
cy.get('[data-project="cart"]').should('be.visible');
cy.get('[data-project="cart"]').click({ force: true });
getSelectTasksMessage().should('not.exist');
});
});
describe('select all button', () => {
it('should check all project items', () => {
getSelectAllButton().scrollIntoView().click({ force: true });
getCheckedProjectItems().should('have.length', 2);
});
});
describe('deselect all button', () => {
it('should uncheck all project items', () => {
getDeselectAllButton().click();
getUncheckedProjectItems().should('have.length', 2);
getSelectTasksMessage().should('be.visible');
});
});
describe('selecting projects', () => {
it('should select a project by clicking on the project name', () => {
cy.get('[data-project="cart"]').should('have.data', 'active', false);
cy.get('[data-project="cart"]').click({
force: true,
});
cy.get('[data-project="cart"][data-active="true"]').should('exist');
});
it('should deselect a project by clicking on the project name again', () => {
cy.get('[data-project="cart"]').click({
force: true,
});
cy.get('[data-project="cart"][data-active="true"]')
.should('exist')
.click({
force: true,
});
cy.get('[data-project="cart"][data-active="false"]').should('exist');
});
it('should select a project by clicking on the selected icon', () => {
cy.get('[data-project="cart"][data-active="false"]').click({
force: true,
});
cy.get('[data-project="cart"][data-active="true"]')
.should('exist')
.parent()
.siblings()
.first()
.should('exist')
.click({
force: true,
});
cy.get('[data-project="cart"][data-active="false"]').should('exist');
});
});
describe('image download button', () => {
it('should be hidden initally', () => {
getImageDownloadButton().should('have.class', 'opacity-0');
});
it('should be shown when a project is selected', () => {
cy.get('[data-project="cart"]').click({ force: true });
getImageDownloadButton().should('not.have.class', 'opacity-0');
});
it('should be hidden when no more projects are selected', () => {
cy.get('[data-project="cart"]').click({ force: true });
getDeselectAllButton().click();
getImageDownloadButton().should('have.class', 'opacity-0');
});
});
describe('setting route params', () => {
it('should set selected target', () => {
getSelectTargetDropdown().select('e2e', { force: true });
cy.url().should('contain', 'tasks/e2e');
});
it('should set group by project', () => {
getGroupByProjectCheckbox().click();
cy.url().should('contain', 'groupByProject=true');
});
});
describe('loading graph client with url params', () => {
beforeEach(() => {
cy.intercept('/assets/project-graphs/*', {
fixture: 'nx-examples-project-graph.json',
}).as('getGraph');
cy.intercept('/assets/task-graphs/e2e.json', {
fixture: 'nx-examples-task-graphs.json',
}).as('getTaskGraphs');
});
// check that params work from old base url of /
// and also new /projects route
testTaskRoutes('browser', ['/e2e/tasks']);
});
});

View File

@ -1,4 +1,4 @@
describe('graph-client release', () => {
describe('release serve-mode app', () => {
beforeEach(() => {
cy.intercept('/assets/project-graphs/*').as('getGraph');

View File

@ -1,6 +1,6 @@
import { testProjectsRoutes } from '../support/routing-tests';
import { testProjectsRoutes, testTaskRoutes } from '../support/routing-tests';
describe('graph-client release', () => {
describe('release static-mode app', () => {
beforeEach(() => {
cy.visit('/');
});
@ -18,6 +18,6 @@ describe('graph-client release', () => {
cy.url().should('contain', '/#/projects');
});
testProjectsRoutes('hash', ['/projects']);
testProjectsRoutes('hash', ['/', '/projects']);
});
});

View File

@ -1,6 +1,6 @@
import { getProjectItems } from '../support/app.po';
describe('graph-client in watch mode', () => {
describe('watch mode - app', () => {
beforeEach(() => {
cy.visit('/projects');
});

View File

@ -0,0 +1,711 @@
{
"taskGraphs": {
"products-product-detail-page:lint": {
"roots": ["products-product-detail-page:lint"],
"tasks": {
"products-product-detail-page:lint": {
"id": "products-product-detail-page:lint",
"target": {
"project": "products-product-detail-page",
"target": "lint"
},
"projectRoot": "libs/products/product-detail-page",
"overrides": {}
}
},
"dependencies": {
"products-product-detail-page:lint": []
}
},
"products-product-detail-page:test": {
"roots": ["products-product-detail-page:test"],
"tasks": {
"products-product-detail-page:test": {
"id": "products-product-detail-page:test",
"target": {
"project": "products-product-detail-page",
"target": "test"
},
"projectRoot": "libs/products/product-detail-page",
"overrides": {}
}
},
"dependencies": {
"products-product-detail-page:test": []
}
},
"shared-product-state:lint": {
"roots": ["shared-product-state:lint"],
"tasks": {
"shared-product-state:lint": {
"id": "shared-product-state:lint",
"target": {
"project": "shared-product-state",
"target": "lint"
},
"projectRoot": "libs/shared/product/state",
"overrides": {}
}
},
"dependencies": {
"shared-product-state:lint": []
}
},
"shared-product-state:test": {
"roots": ["shared-product-state:test"],
"tasks": {
"shared-product-state:test": {
"id": "shared-product-state:test",
"target": {
"project": "shared-product-state",
"target": "test"
},
"projectRoot": "libs/shared/product/state",
"overrides": {}
}
},
"dependencies": {
"shared-product-state:test": []
}
},
"shared-product-types:lint": {
"roots": ["shared-product-types:lint"],
"tasks": {
"shared-product-types:lint": {
"id": "shared-product-types:lint",
"target": {
"project": "shared-product-types",
"target": "lint"
},
"projectRoot": "libs/shared/product/types",
"overrides": {}
}
},
"dependencies": {
"shared-product-types:lint": []
}
},
"shared-product-data:lint": {
"roots": ["shared-product-data:lint"],
"tasks": {
"shared-product-data:lint": {
"id": "shared-product-data:lint",
"target": {
"project": "shared-product-data",
"target": "lint"
},
"projectRoot": "libs/shared/product/data",
"overrides": {}
}
},
"dependencies": {
"shared-product-data:lint": []
}
},
"products-home-page:lint": {
"roots": ["products-home-page:lint"],
"tasks": {
"products-home-page:lint": {
"id": "products-home-page:lint",
"target": {
"project": "products-home-page",
"target": "lint"
},
"projectRoot": "libs/products/home-page",
"overrides": {}
}
},
"dependencies": {
"products-home-page:lint": []
}
},
"products-home-page:test": {
"roots": ["products-home-page:test"],
"tasks": {
"products-home-page:test": {
"id": "products-home-page:test",
"target": {
"project": "products-home-page",
"target": "test"
},
"projectRoot": "libs/products/home-page",
"overrides": {}
}
},
"dependencies": {
"products-home-page:test": []
}
},
"shared-cart-state:lint": {
"roots": ["shared-cart-state:lint"],
"tasks": {
"shared-cart-state:lint": {
"id": "shared-cart-state:lint",
"target": {
"project": "shared-cart-state",
"target": "lint"
},
"projectRoot": "libs/shared/cart/state",
"overrides": {}
}
},
"dependencies": {
"shared-cart-state:lint": []
}
},
"shared-cart-state:test": {
"roots": ["shared-cart-state:test"],
"tasks": {
"shared-cart-state:test": {
"id": "shared-cart-state:test",
"target": {
"project": "shared-cart-state",
"target": "test"
},
"projectRoot": "libs/shared/cart/state",
"overrides": {}
}
},
"dependencies": {
"shared-cart-state:test": []
}
},
"shared-product-ui:lint": {
"roots": ["shared-product-ui:lint"],
"tasks": {
"shared-product-ui:lint": {
"id": "shared-product-ui:lint",
"target": {
"project": "shared-product-ui",
"target": "lint"
},
"projectRoot": "libs/shared/product/ui",
"overrides": {}
}
},
"dependencies": {
"shared-product-ui:lint": []
}
},
"shared-product-ui:test": {
"roots": ["shared-product-ui:test"],
"tasks": {
"shared-product-ui:test": {
"id": "shared-product-ui:test",
"target": {
"project": "shared-product-ui",
"target": "test"
},
"projectRoot": "libs/shared/product/ui",
"overrides": {}
}
},
"dependencies": {
"shared-product-ui:test": []
}
},
"shared-e2e-utils:lint": {
"roots": ["shared-e2e-utils:lint"],
"tasks": {
"shared-e2e-utils:lint": {
"id": "shared-e2e-utils:lint",
"target": {
"project": "shared-e2e-utils",
"target": "lint"
},
"projectRoot": "libs/shared/e2e-utils",
"overrides": {}
}
},
"dependencies": {
"shared-e2e-utils:lint": []
}
},
"cart-cart-page:lint": {
"roots": ["cart-cart-page:lint"],
"tasks": {
"cart-cart-page:lint": {
"id": "cart-cart-page:lint",
"target": {
"project": "cart-cart-page",
"target": "lint"
},
"projectRoot": "libs/cart/cart-page",
"overrides": {}
}
},
"dependencies": {
"cart-cart-page:lint": []
}
},
"cart-cart-page:test": {
"roots": ["cart-cart-page:test"],
"tasks": {
"cart-cart-page:test": {
"id": "cart-cart-page:test",
"target": {
"project": "cart-cart-page",
"target": "test"
},
"projectRoot": "libs/cart/cart-page",
"overrides": {}
}
},
"dependencies": {
"cart-cart-page:test": []
}
},
"shared-header:lint": {
"roots": ["shared-header:lint"],
"tasks": {
"shared-header:lint": {
"id": "shared-header:lint",
"target": {
"project": "shared-header",
"target": "lint"
},
"projectRoot": "libs/shared/header",
"overrides": {}
}
},
"dependencies": {
"shared-header:lint": []
}
},
"shared-header:test": {
"roots": ["shared-header:test"],
"tasks": {
"shared-header:test": {
"id": "shared-header:test",
"target": {
"project": "shared-header",
"target": "test"
},
"projectRoot": "libs/shared/header",
"overrides": {}
}
},
"dependencies": {
"shared-header:test": []
}
},
"shared-jsxify:lint": {
"roots": ["shared-jsxify:lint"],
"tasks": {
"shared-jsxify:lint": {
"id": "shared-jsxify:lint",
"target": {
"project": "shared-jsxify",
"target": "lint"
},
"projectRoot": "libs/shared/jsxify",
"overrides": {}
}
},
"dependencies": {
"shared-jsxify:lint": []
}
},
"products-e2e:e2e": {
"roots": ["products-e2e:e2e"],
"tasks": {
"products-e2e:e2e": {
"id": "products-e2e:e2e",
"target": {
"project": "products-e2e",
"target": "e2e"
},
"projectRoot": "apps/products-e2e",
"overrides": {}
}
},
"dependencies": {
"products-e2e:e2e": []
}
},
"products-e2e:e2e:production": {
"roots": ["products-e2e:e2e:production"],
"tasks": {
"products-e2e:e2e:production": {
"id": "products-e2e:e2e:production",
"target": {
"project": "products-e2e",
"target": "e2e",
"configuration": "production"
},
"projectRoot": "apps/products-e2e",
"overrides": {}
}
},
"dependencies": {
"products-e2e:e2e:production": []
}
},
"products-e2e:lint": {
"roots": ["products-e2e:lint"],
"tasks": {
"products-e2e:lint": {
"id": "products-e2e:lint",
"target": {
"project": "products-e2e",
"target": "lint"
},
"projectRoot": "apps/products-e2e",
"overrides": {}
}
},
"dependencies": {
"products-e2e:lint": []
}
},
"cart-e2e:e2e": {
"roots": ["cart-e2e:e2e"],
"tasks": {
"cart-e2e:e2e": {
"id": "cart-e2e:e2e",
"target": {
"project": "cart-e2e",
"target": "e2e"
},
"projectRoot": "apps/cart-e2e",
"overrides": {}
}
},
"dependencies": {
"cart-e2e:e2e": []
}
},
"cart-e2e:e2e:production": {
"roots": ["cart-e2e:e2e:production"],
"tasks": {
"cart-e2e:e2e:production": {
"id": "cart-e2e:e2e:production",
"target": {
"project": "cart-e2e",
"target": "e2e",
"configuration": "production"
},
"projectRoot": "apps/cart-e2e",
"overrides": {}
}
},
"dependencies": {
"cart-e2e:e2e:production": []
}
},
"cart-e2e:lint": {
"roots": ["cart-e2e:lint"],
"tasks": {
"cart-e2e:lint": {
"id": "cart-e2e:lint",
"target": {
"project": "cart-e2e",
"target": "lint"
},
"projectRoot": "apps/cart-e2e",
"overrides": {}
}
},
"dependencies": {
"cart-e2e:lint": []
}
},
"products:build": {
"roots": ["products:build"],
"tasks": {
"products:build": {
"id": "products:build",
"target": {
"project": "products",
"target": "build"
},
"projectRoot": "apps/products",
"overrides": {}
}
},
"dependencies": {
"products:build": []
}
},
"products:build:production": {
"roots": ["products:build:production"],
"tasks": {
"products:build:production": {
"id": "products:build:production",
"target": {
"project": "products",
"target": "build",
"configuration": "production"
},
"projectRoot": "apps/products",
"overrides": {}
}
},
"dependencies": {
"products:build:production": []
}
},
"products:serve": {
"roots": ["products:serve"],
"tasks": {
"products:serve": {
"id": "products:serve",
"target": {
"project": "products",
"target": "serve"
},
"projectRoot": "apps/products",
"overrides": {}
}
},
"dependencies": {
"products:serve": []
}
},
"products:serve:production": {
"roots": ["products:serve:production"],
"tasks": {
"products:serve:production": {
"id": "products:serve:production",
"target": {
"project": "products",
"target": "serve",
"configuration": "production"
},
"projectRoot": "apps/products",
"overrides": {}
}
},
"dependencies": {
"products:serve:production": []
}
},
"products:extract-i18n": {
"roots": ["products:extract-i18n"],
"tasks": {
"products:extract-i18n": {
"id": "products:extract-i18n",
"target": {
"project": "products",
"target": "extract-i18n"
},
"projectRoot": "apps/products",
"overrides": {}
}
},
"dependencies": {
"products:extract-i18n": []
}
},
"products:lint": {
"roots": ["products:lint"],
"tasks": {
"products:lint": {
"id": "products:lint",
"target": {
"project": "products",
"target": "lint"
},
"projectRoot": "apps/products",
"overrides": {}
}
},
"dependencies": {
"products:lint": []
}
},
"products:test": {
"roots": ["products:test"],
"tasks": {
"products:test": {
"id": "products:test",
"target": {
"project": "products",
"target": "test"
},
"projectRoot": "apps/products",
"overrides": {}
}
},
"dependencies": {
"products:test": []
}
},
"products:deploy": {
"roots": ["products:deploy"],
"tasks": {
"products:deploy": {
"id": "products:deploy",
"target": {
"project": "products",
"target": "deploy"
},
"projectRoot": "apps/products",
"overrides": {}
}
},
"dependencies": {
"products:deploy": []
}
},
"cart:build": {
"roots": ["cart:build:production"],
"tasks": {
"cart:build:production": {
"id": "cart:build:production",
"target": {
"project": "cart",
"target": "build",
"configuration": "production"
},
"projectRoot": "apps/cart",
"overrides": {}
}
},
"dependencies": {
"cart:build:production": []
}
},
"cart:build:production": {
"roots": ["cart:build:production"],
"tasks": {
"cart:build:production": {
"id": "cart:build:production",
"target": {
"project": "cart",
"target": "build",
"configuration": "production"
},
"projectRoot": "apps/cart",
"overrides": {}
}
},
"dependencies": {
"cart:build:production": []
}
},
"cart:build:development": {
"roots": ["cart:build:development"],
"tasks": {
"cart:build:development": {
"id": "cart:build:development",
"target": {
"project": "cart",
"target": "build",
"configuration": "development"
},
"projectRoot": "apps/cart",
"overrides": {}
}
},
"dependencies": {
"cart:build:development": []
}
},
"cart:serve": {
"roots": ["cart:serve:development"],
"tasks": {
"cart:serve:development": {
"id": "cart:serve:development",
"target": {
"project": "cart",
"target": "serve",
"configuration": "development"
},
"projectRoot": "apps/cart",
"overrides": {}
}
},
"dependencies": {
"cart:serve:development": []
}
},
"cart:serve:production": {
"roots": ["cart:serve:production"],
"tasks": {
"cart:serve:production": {
"id": "cart:serve:production",
"target": {
"project": "cart",
"target": "serve",
"configuration": "production"
},
"projectRoot": "apps/cart",
"overrides": {}
}
},
"dependencies": {
"cart:serve:production": []
}
},
"cart:serve:development": {
"roots": ["cart:serve:development"],
"tasks": {
"cart:serve:development": {
"id": "cart:serve:development",
"target": {
"project": "cart",
"target": "serve",
"configuration": "development"
},
"projectRoot": "apps/cart",
"overrides": {}
}
},
"dependencies": {
"cart:serve:development": []
}
},
"cart:lint": {
"roots": ["cart:lint"],
"tasks": {
"cart:lint": {
"id": "cart:lint",
"target": {
"project": "cart",
"target": "lint"
},
"projectRoot": "apps/cart",
"overrides": {}
}
},
"dependencies": {
"cart:lint": []
}
},
"cart:test": {
"roots": ["cart:test"],
"tasks": {
"cart:test": {
"id": "cart:test",
"target": {
"project": "cart",
"target": "test"
},
"projectRoot": "apps/cart",
"overrides": {}
}
},
"dependencies": {
"cart:test": []
}
},
"cart:deploy": {
"roots": ["cart:deploy"],
"tasks": {
"cart:deploy": {
"id": "cart:deploy",
"target": {
"project": "cart",
"target": "deploy"
},
"projectRoot": "apps/cart",
"overrides": {}
}
},
"dependencies": {
"cart:deploy": []
}
}
}
}

View File

@ -1,5 +1,7 @@
export const getSelectProjectsMessage = () =>
cy.contains('Please select a project in the sidebar');
export const getSelectTasksMessage = () =>
cy.contains('Please select a task in the sidebar');
export const getGraph = () => cy.get('#graph-container');
export const getSelectAllButton = () => cy.get('[data-cy=selectAllButton]');
export const getDeselectAllButton = () => cy.get('[data-cy=deselectAllButton]');
@ -16,6 +18,9 @@ export const getUncheckedProjectItems = () => cy.get('[data-active="false"]');
export const getGroupByFolderCheckbox = () =>
cy.get('input[name=groupByFolder]');
export const getGroupByProjectCheckbox = () =>
cy.get('input[name=groupByProject]');
export const getSearchDepthCheckbox = () =>
cy.get('input[name=depthFilter][value=depthFilterActivated]');
export const getTextFilterInput = () => cy.get('[data-cy=textFilterInput]');
@ -37,3 +42,6 @@ export const getFocusButtonForProject = (projectName: string) =>
export const getToggleAllButtonForFolder = (folderName: string) =>
cy.get(`[data-cy="toggle-folder-visibility-button-${folderName}"]`);
export const getSelectTargetDropdown = () =>
cy.get('[data-cy=selected-target-dropdown]');

View File

@ -1,17 +1,25 @@
import * as nxExamplesJson from '../fixtures/nx-examples.json';
import * as nxExamplesJson from '../fixtures/nx-examples-project-graph.json';
import {
getCheckedProjectItems,
getGroupByFolderCheckbox,
getGroupByProjectCheckbox,
getSearchDepthCheckbox,
getSelectTargetDropdown,
} from './app.po';
function waitForGraph(router: 'hash' | 'browser') {
function waitForProjectGraph(router: 'hash' | 'browser') {
if (router === 'browser') {
cy.wait('@getGraph');
}
}
function resolveRoute(
function waitForTaskGraphs(router: 'hash' | 'browser') {
if (router === 'browser') {
cy.wait('@getTaskGraphs');
}
}
function resolveProjectsRoute(
router: 'hash' | 'browser',
route: string,
paramString: string
@ -22,6 +30,19 @@ function resolveRoute(
return `${route}?${paramString}`;
}
}
function resolveTasksRoute(
router: 'hash' | 'browser',
route: string,
paramString: string
) {
if (router === 'hash') {
return `/#${route}?${paramString}`;
} else {
return `${route}?${paramString}`;
}
}
export function testProjectsRoutes(
router: 'hash' | 'browser',
routes: string[]
@ -29,10 +50,10 @@ export function testProjectsRoutes(
routes.forEach((route) => {
describe(`for route ${route}`, () => {
it('should focus projects', () => {
cy.visit(resolveRoute(router, route, 'focus=cart'));
cy.visit(resolveProjectsRoute(router, route, 'focus=cart'));
// wait for first graph to finish loading
waitForGraph(router);
waitForProjectGraph(router);
const dependencies = nxExamplesJson.dependencies.cart;
const dependents = Object.keys(nxExamplesJson.dependencies).filter(
@ -48,20 +69,24 @@ export function testProjectsRoutes(
});
it('should focus projects with search depth', () => {
cy.visit(resolveRoute(router, route, `focus=cart&searchDepth=2`));
cy.visit(
resolveProjectsRoute(router, route, `focus=cart&searchDepth=2`)
);
// wait for first graph to finish loading
waitForGraph(router);
waitForProjectGraph(router);
getCheckedProjectItems().should('have.length', 10);
getSearchDepthCheckbox().should('exist');
});
it('should focus projects with search depth disabled', () => {
cy.visit(resolveRoute(router, route, `focus=cart&searchDepth=0`));
cy.visit(
resolveProjectsRoute(router, route, `focus=cart&searchDepth=0`)
);
// wait for first graph to finish loading
waitForGraph(router);
waitForProjectGraph(router);
getCheckedProjectItems().should('have.length', 12);
getSearchDepthCheckbox().should('exist');
@ -69,7 +94,7 @@ export function testProjectsRoutes(
it('should set group by folder', () => {
cy.visit(
resolveRoute(
resolveProjectsRoute(
router,
route,
`focus=nx-dev&searchDepth=1&groupByFolder=true`
@ -77,16 +102,16 @@ export function testProjectsRoutes(
);
// wait for first graph to finish loading
waitForGraph(router);
waitForProjectGraph(router);
getGroupByFolderCheckbox().should('be.checked');
});
it('should select all projects', () => {
cy.visit(resolveRoute(router, route, `select=all`));
cy.visit(resolveProjectsRoute(router, route, `select=all`));
// wait for first graph to finish loading
waitForGraph(router);
waitForProjectGraph(router);
getCheckedProjectItems().should(
'have.length',
@ -96,3 +121,29 @@ export function testProjectsRoutes(
});
});
}
export function testTaskRoutes(router: 'hash' | 'browser', routes: string[]) {
routes.forEach((route) => {
describe(`for route ${route}`, () => {
it('should set group by project', () => {
cy.visit(resolveTasksRoute(router, route, `groupByProject=true`));
// wait for first graph to finish loading
waitForProjectGraph(router);
waitForTaskGraphs(router);
getGroupByProjectCheckbox().should('be.checked');
});
it('should set selected target', () => {
cy.visit(resolveTasksRoute(router, `${route}/e2e`, ''));
// wait for first graph to finish loading
waitForProjectGraph(router);
waitForTaskGraphs(router);
getSelectTargetDropdown().should('have.value', 'e2e');
});
});
});
}

View File

@ -133,7 +133,12 @@
"graph/client/src/favicon.ico",
{
"input": "graph/client/src/assets/project-graphs",
"output": "/assets/graphs",
"output": "/assets/project-graphs",
"glob": "e2e.json"
},
{
"input": "graph/client/src/assets/task-graphs",
"output": "/assets/task-graphs",
"glob": "e2e.json"
},
{

View File

@ -279,7 +279,7 @@ export function ProjectList() {
);
})}
<h2 className="mt-8 border-b border-solid border-slate-200/10 text-lg font-light">
<h2 className="mt-8 border-b border-solid border-slate-200/10 text-lg font-light text-slate-400 dark:text-slate-500">
e2e projects
</h2>
@ -294,7 +294,7 @@ export function ProjectList() {
);
})}
<h2 className="mt-8 border-b border-solid border-slate-200/10 text-lg font-light">
<h2 className="mt-8 border-b border-solid border-slate-200/10 text-lg font-light text-slate-400 dark:text-slate-500">
lib projects
</h2>

View File

@ -10,18 +10,6 @@ interface SidebarProject {
isSelected: boolean;
}
function createTaskName(
project: string,
target: string,
configuration?: string
) {
if (configuration) {
return `${project}:${target}:${configuration}`;
} else {
return `${project}:${target}`;
}
}
function ProjectListItem({
project,
toggleTask,
@ -163,7 +151,7 @@ export function TaskList({
);
})}
<h2 className="mt-8 border-b border-solid border-slate-200/10 text-lg font-light">
<h2 className="mt-8 border-b border-solid border-slate-200/10 text-lg font-light text-slate-400 dark:text-slate-500">
e2e projects
</h2>
@ -180,7 +168,7 @@ export function TaskList({
);
})}
<h2 className="mt-8 border-b border-solid border-slate-200/10 text-lg font-light">
<h2 className="mt-8 border-b border-solid border-slate-200/10 text-lg font-light text-slate-400 dark:text-slate-500">
lib projects
</h2>

View File

@ -18,6 +18,18 @@ import CheckboxPanel from '../ui-components/checkbox-panel';
import Dropdown from '../ui-components/dropdown';
import ShowHideAll from '../ui-components/show-hide-all';
function createTaskName(
project: string,
target: string,
configuration?: string
) {
if (configuration) {
return `${project}:${target}:${configuration}`;
} else {
return `${project}:${target}`;
}
}
export function TasksSidebar() {
const graphService = getGraphService();
const navigate = useNavigate();
@ -63,7 +75,7 @@ export function TasksSidebar() {
function selectProject(project: string) {
setSelectedProjects([...selectedProjects, project]);
const taskId = `${project}:${selectedTarget}`;
const taskId = createTaskName(project, selectedTarget);
graphService.handleTaskEvent({
type: 'notifyTaskGraphTasksSelected',
@ -187,6 +199,7 @@ export function TasksSidebar() {
<Dropdown
id="selectedTarget"
className="w-full"
data-cy="selected-target-dropdown"
defaultValue={selectedTarget}
onChange={(event) => selectTarget(event.currentTarget.value)}
>

View File

@ -56,12 +56,6 @@ const childRoutes: RouteObject[] = [
},
{
loader: async ({ request, params }) => {
const environmentConfig = getEnvironmentConfig();
if (!environmentConfig.appConfig.showExperimentalFeatures) {
return redirect(`/projects`);
}
const selectedWorkspaceId =
params.selectedWorkspaceId ?? appConfig.defaultWorkspaceId;
return taskDataLoader(selectedWorkspaceId);

File diff suppressed because it is too large Load Diff