Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move react-components code into react-client #813

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ I've copy/pasted the whole document there, without the previous two headings.
- [Install python dependencies](#install-python-dependencies)
- [Start the Chainlit server from source](#start-the-chainlit-server-from-source)
- [Start the UI from source](#start-the-ui-from-source)
- [Develop locally on `libs/react-components`](#develop-locally-on-libsreact-components)
- [Run the tests](#run-the-tests)
- [Run one test](#run-one-test)

Expand Down Expand Up @@ -117,19 +116,6 @@ pnpm run dev --port 5174

If you visit `http://127.0.0.1:5174/`, it should connect to your local server. If the local server is not running, it should say that it can't connect to the server.

## Develop locally on `libs/react-components`

Reusable UI components are living in the separate npm package `libs/react-components`. The main Chainlit UI build and import that package automatically.

You can enable hot module replacement for development.

```sh
cd libs/react-components
pnpm run build:watch
```

This will watch for file changes in `libs/react-components` and automatically rebuild the library as you develop.

## Run the tests

Run `pnpm test`
Expand Down
33 changes: 0 additions & 33 deletions .github/workflows/tests-components.yaml

This file was deleted.

15 changes: 15 additions & 0 deletions cypress/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
rules: {
'no-undef': 'warn',
'@typescript-eslint/no-var-requires': 'warn',
'cypress/no-unnecessary-waiting': 'warn',
'cypress/unsafe-to-chain-command': 'warn',
'cypress/no-assigning-return-values': 'warn',
'no-sparse-arrays': 'warn'
},
env: {
node: true,
'cypress/globals': true
},
extends: ['plugin:cypress/recommended']
};
60 changes: 60 additions & 0 deletions cypress/e2e/action/spec.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var testUtils_1 = require('../../support/testUtils');
describe('Action', function () {
before(function () {
(0, testUtils_1.runTestServer)();
});
it('should correctly execute and display actions', function () {
// Click on "first action"
cy.get('#first-action').should('exist');
cy.get('#first-action').click();
cy.get('.step').should('have.length', 3);
cy.get('.step')
.eq(2)
.should('contain', 'Thanks for pressing: first-action');
// Click on "test action"
cy.get("[id='test-action']").should('exist');
cy.get("[id='test-action']").click();
cy.get('.step').should('have.length', 4);
cy.get('.step').eq(3).should('contain', 'Executed test action!');
cy.get("[id='test-action']").should('exist');
cy.wait(100);
// Click on "removable action"
cy.get("[id='removable-action']").should('exist');
cy.get("[id='removable-action']").click();
cy.get('.step').should('have.length', 5);
cy.get('.step').eq(4).should('contain', 'Executed removable action!');
cy.get("[id='removable-action']").should('not.exist');
cy.wait(100);
// Click on "multiple action one" in the action drawer, should remove the correct action button
cy.get("[id='actions-drawer-button']").should('exist');
cy.get("[id='actions-drawer-button']").click();
cy.get('.step').should('have.length', 5);
cy.wait(100);
cy.get("[id='multiple-action-one']").should('exist');
cy.get("[id='multiple-action-one']").click();
cy.get('.step')
.eq(5)
.should('contain', 'Action(id=multiple-action-one) has been removed!');
cy.get("[id='multiple-action-one']").should('not.exist');
cy.wait(100);
// Click on "multiple action two", should remove the correct action button
cy.get('.step').should('have.length', 6);
cy.get("[id='actions-drawer-button']").click();
cy.get("[id='multiple-action-two']").should('exist');
cy.get("[id='multiple-action-two']").click();
cy.get('.step')
.eq(6)
.should('contain', 'Action(id=multiple-action-two) has been removed!');
cy.get("[id='multiple-action-two']").should('not.exist');
cy.wait(100);
// Click on "all actions removed", should remove all buttons
cy.get("[id='all-actions-removed']").should('exist');
cy.get("[id='all-actions-removed']").click();
cy.get('.step').eq(7).should('contain', 'All actions have been removed!');
cy.get("[id='all-actions-removed']").should('not.exist');
cy.get("[id='test-action']").should('not.exist');
cy.get("[id='actions-drawer-button']").should('not.exist');
});
});
36 changes: 36 additions & 0 deletions cypress/e2e/ask_file/spec.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var testUtils_1 = require('../../support/testUtils');
describe('Upload file', function () {
before(function () {
(0, testUtils_1.runTestServer)();
});
it('should be able to receive and decode files', function () {
cy.get('#ask-upload-button').should('exist');
// Upload a text file
cy.fixture('state_of_the_union.txt', 'utf-8').as('txtFile');
cy.get('#ask-button-input').selectFile('@txtFile', { force: true });
// Sometimes the loading indicator is not shown because the file upload is too fast
// cy.get("#ask-upload-button-loading").should("exist");
// cy.get("#ask-upload-button-loading").should("not.exist");
cy.get('.step')
.eq(1)
.should(
'contain',
'Text file state_of_the_union.txt uploaded, it contains'
);
cy.get('#ask-upload-button').should('exist');
// Expecting a python file, cpp file upload should be rejected
cy.fixture('hello.cpp', 'utf-8').as('cppFile');
cy.get('#ask-button-input').selectFile('@cppFile', { force: true });
cy.get('.step').should('have.length', 3);
// Upload a python file
cy.fixture('hello.py', 'utf-8').as('pyFile');
cy.get('#ask-button-input').selectFile('@pyFile', { force: true });
cy.get('.step')
.should('have.length', 4)
.eq(3)
.should('contain', 'Python file hello.py uploaded, it contains');
cy.get('#ask-upload-button').should('not.exist');
});
});
23 changes: 23 additions & 0 deletions cypress/e2e/ask_multiple_files/spec.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var testUtils_1 = require('../../support/testUtils');
describe('Upload multiple files', function () {
before(function () {
(0, testUtils_1.runTestServer)();
});
it('should be able to receive two files', function () {
cy.get('#ask-upload-button').should('exist');
cy.fixture('state_of_the_union.txt', 'utf-8').as('txtFile');
cy.fixture('hello.py', 'utf-8').as('pyFile');
cy.get('#ask-button-input').selectFile(['@txtFile', '@pyFile'], {
force: true
});
// Sometimes the loading indicator is not shown because the file upload is too fast
// cy.get("#ask-upload-button-loading").should("exist");
// cy.get("#ask-upload-button-loading").should("not.exist");
cy.get('.step')
.eq(1)
.should('contain', '2 files uploaded: state_of_the_union.txt,hello.py');
cy.get('#ask-upload-button').should('not.exist');
});
});
15 changes: 15 additions & 0 deletions cypress/e2e/ask_user/spec.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var testUtils_1 = require('../../support/testUtils');
describe('Ask User', function () {
before(function () {
(0, testUtils_1.runTestServer)();
});
it('should send a new message containing the user input', function () {
cy.get('.step').should('have.length', 1);
(0, testUtils_1.submitMessage)('Jeeves');
cy.wait(2000);
cy.get('.step').should('have.length', 3);
cy.get('.step').eq(2).should('contain', 'Jeeves');
});
});
20 changes: 20 additions & 0 deletions cypress/e2e/audio_element/spec.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var testUtils_1 = require('../../support/testUtils');
describe('audio', function () {
before(function () {
(0, testUtils_1.runTestServer)();
});
it('should be able to display an audio element', function () {
cy.get('.step').should('have.length', 1);
cy.get('.step').eq(0).find('.inline-audio').should('have.length', 1);
cy.get('.inline-audio audio')
.then(function ($el) {
var audioElement = $el.get(0);
return audioElement.play().then(function () {
return audioElement.duration;
});
})
.should('be.greaterThan', 0);
});
});
12 changes: 12 additions & 0 deletions cypress/e2e/author_rename/spec.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var testUtils_1 = require('../../support/testUtils');
describe('Author rename', function () {
before(function () {
(0, testUtils_1.runTestServer)();
});
it('should be able to rename authors', function () {
cy.get('.step').eq(0).should('contain', 'Albert Einstein');
cy.get('.step').eq(1).should('contain', 'Assistant');
});
});
17 changes: 17 additions & 0 deletions cypress/e2e/avatar/spec.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var testUtils_1 = require('../../support/testUtils');
describe('Avatar', function () {
before(function () {
(0, testUtils_1.runTestServer)();
});
it('should be able to display avatars', function () {
cy.get('.step').should('have.length', 5);
cy.get('.step').eq(0).find('img').should('have.length', 0);
cy.get('.step').eq(1).find('img').should('have.length', 1);
cy.get('.step').eq(2).find('img').should('have.length', 0);
cy.get('.step').eq(3).find('img').should('have.length', 1);
cy.get('.step').eq(4).find('img').should('have.length', 1);
cy.get('.element-link').should('have.length', 0);
});
});
55 changes: 55 additions & 0 deletions cypress/e2e/chat_profiles/spec.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var testUtils_1 = require('../../support/testUtils');
describe('Chat profiles', function () {
before(function () {
(0, testUtils_1.runTestServer)();
});
it('should be able to select a chat profile', function () {
cy.visit('/');
cy.get("input[name='email']").type('admin');
cy.get("input[name='password']").type('admin');
cy.get("button[type='submit']").click();
cy.get('.MuiAlert-message').should('not.exist');
cy.get('#chat-input').should('exist');
cy.get('[data-test="chat-profile:GPT-3.5"]').should('exist');
cy.get('[data-test="chat-profile:GPT-4"]').should('exist');
cy.get('[data-test="chat-profile:GPT-5"]').should('exist');
cy.get('.step')
.should('have.length', 1)
.eq(0)
.should(
'contain',
'starting chat with admin using the GPT-3.5 chat profile'
);
// Change chat profile
cy.get('[data-test="chat-profile:GPT-4"]').click();
cy.get('.step')
.should('have.length', 1)
.eq(0)
.should(
'contain',
'starting chat with admin using the GPT-4 chat profile'
);
cy.get('#new-chat-button').click();
cy.get('#confirm').click();
cy.get('.step')
.should('have.length', 1)
.eq(0)
.should(
'contain',
'starting chat with admin using the GPT-4 chat profile'
);
(0, testUtils_1.submitMessage)('hello');
cy.get('.step').should('have.length', 2).eq(1).should('contain', 'hello');
cy.get('[data-test="chat-profile:GPT-5"]').click();
cy.get('#confirm').click();
cy.get('.step')
.should('have.length', 1)
.eq(0)
.should(
'contain',
'starting chat with admin using the GPT-5 chat profile'
);
});
});
41 changes: 41 additions & 0 deletions cypress/e2e/chat_settings/spec.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var testUtils_1 = require('../../support/testUtils');
describe('Customize chat settings', function () {
before(function () {
(0, testUtils_1.runTestServer)();
});
it('should update inputs', function () {
// Open chat settings modal
cy.get('#chat-settings-open-modal').should('exist');
cy.get('#chat-settings-open-modal').click();
cy.get('#chat-settings-dialog').should('exist');
// Update inputs
cy.get('#mui-component-select-Model').click();
cy.contains('gpt-4').click();
cy.get('#Model').should('have.value', 'gpt-4');
cy.get('#Temperature').clear().type('0.4');
cy.get('#Temperature').should('have.value', '0.4');
cy.get('#SAI_Steps').clear().type('5');
cy.get('#SAI_Steps').should('have.value', '50');
cy.get('#SAI_Cfg_Scale').clear().type('2');
cy.get('#SAI_Cfg_Scale').should('have.value', '20');
cy.get('#SAI_Width').clear().type('140');
cy.get('#SAI_Width').should('have.value', '1400');
cy.get('#SAI_Height').clear().type('140');
cy.get('#SAI_Height').should('have.value', '1400');
cy.contains('Confirm').click();
cy.get('.step').should('have.length', 1);
cy.get('.step').eq(0).should('contain', 'Settings updated!');
// Check if inputs are updated
cy.get('#chat-settings-open-modal').click();
cy.get('#Temperature').should('have.value', '0.4');
cy.get('#SAI_Steps').should('have.value', '50');
cy.get('#SAI_Cfg_Scale').should('have.value', '20');
cy.get('#SAI_Width').should('have.value', '1400');
cy.get('#SAI_Height').should('have.value', '1400');
// Check if modal is correctly closed
cy.contains('Cancel').click();
cy.get('#chat-settings-dialog').should('not.exist');
});
});
16 changes: 16 additions & 0 deletions cypress/e2e/context/spec.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var testUtils_1 = require('../../support/testUtils');
describe('Context should be reachable', function () {
before(function () {
(0, testUtils_1.runTestServer)();
});
it('should find the Emitter from async, make_async and async_from_sync contexts', function () {
cy.get('.step').should('have.length', 3);
cy.get('.step').eq(0).should('contain', 'emitter from async found!');
cy.get('.step').eq(1).should('contain', 'emitter from make_async found!');
cy.get('.step')
.eq(2)
.should('contain', 'emitter from async_from_sync found!');
});
});
Loading