Skip to content

Commit 0dcaa97

Browse files
authored
Merge branch 'master' into 346-add-timeout-configuration
2 parents 524c150 + a1af195 commit 0dcaa97

File tree

18 files changed

+882
-0
lines changed

18 files changed

+882
-0
lines changed

.github/workflows/main.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,45 @@ jobs:
172172
- name: Run tests
173173
run: |
174174
pytest -m 'vetiver'
175+
176+
test-jupyter:
177+
runs-on: ubuntu-latest
178+
env:
179+
CONNECT_LICENSE: ${{ secrets.RSC_LICENSE }}
180+
ADMIN_API_KEY: ${{ secrets.ADMIN_API_KEY }}
181+
steps:
182+
- uses: actions/checkout@v2
183+
env:
184+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
185+
- uses: extractions/setup-just@v1
186+
- name: Build Containers
187+
run: |
188+
just integration-testing/build
189+
- name: Start Connect + rsconnect-jupyter
190+
run: |
191+
just integration-testing/up
192+
193+
- name: Run Cypress Tests
194+
run: |
195+
export ADMIN_API_KEY="${{ secrets.ADMIN_API_KEY }}"
196+
just integration-testing/up-cypress
197+
198+
# Videos are captured whether the suite fails or passes
199+
- name: Save videos
200+
uses: actions/upload-artifact@v3
201+
if: success() || failure()
202+
with:
203+
name: cypress-videos
204+
path: integration-testing/cypress/videos
205+
if-no-files-found: ignore
206+
retention-days: 1
207+
208+
# Screenshots are only captured on failure
209+
- name: Save screenshots
210+
uses: actions/upload-artifact@v3
211+
if: failure()
212+
with:
213+
name: cypress-screenshots
214+
path: integration-testing/cypress/screenshots
215+
if-no-files-found: ignore
216+
retention-days: 1

integration-testing/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/client-python/
2+
/cypress/videos/
3+
/cypress/screenshots/
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Stock Report
2+
3+
## About this example
4+
5+
This stock report is generated using Python and Jupyter Notebook. Stock prices are populated from Quandl to generate a stock performance summary intended to run daily after market close.
6+
7+
8+
## Learn more
9+
10+
* [Jupyter Homepage](https://jupyter.org/)
11+
* [Jupyter Documentation](https://jupyter.org/documentation)
12+
* [Using Jupyter Notebooks in {systemDisplayName}](https://docs.rstudio.com/connect/user/jupyter-notebook/)
13+
* [User Guide for rsconnect_jupyter](https://docs.rstudio.com/rsconnect-jupyter/)
14+
15+
## Requirements
16+
17+
* Python version 3.7 or higher
18+
19+
<!-- NOTE: this file is generated -->
47.6 KB
Binary file not shown.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
jupyter==1.0.0
2+
matplotlib>=3.0.3<=3.5.1
3+
pandas>=0.25.3,<=1.4.1

integration-testing/content/notebook/stock-report-jupyter.ipynb

Lines changed: 464 additions & 0 deletions
Large diffs are not rendered by default.
91.5 KB
Loading
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// {
2+
// "testFiles": "**/*.spec.js",
3+
// "defaultCommandTimeout": 10000,
4+
// "responseTimeout": 60000,
5+
// "integrationFolder": "./cypress/integration/",
6+
// "viewportHeight": 800
7+
// }
8+
9+
const { defineConfig } = require('cypress')
10+
11+
module.exports = defineConfig({
12+
defaultCommandTimeout: 10000,
13+
responseTimeout: 60000,
14+
component: {
15+
viewportHeight: 800
16+
},
17+
e2e: {
18+
defaultCommandTimeout: 10000,
19+
specPattern: "cypress/e2e/**/*.cy.js",
20+
},
21+
})
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
describe('Publishing Jupyter Notebook', () => {
2+
3+
it('Publish button loads', () => {
4+
cy.visit('http://client:9999/tree/integration-testing/content/notebook/stock-report-jupyter.ipynb');
5+
cy.get('button[data-jupyter-action="rsconnect_jupyter:publish"]').click();
6+
cy.get('a[id="publish-to-connect"]').should('be.visible')
7+
});
8+
// wait is required after every action, cypress is too fast for jupyter
9+
// https://github.com/cypress-io/cypress/issues/249
10+
it('Add Server', () => {
11+
cy.visit('http://client:9999/tree/integration-testing/content/notebook/stock-report-jupyter.ipynb');
12+
cy.wait(1000);
13+
cy.get('a[id="publish-to-connect"]').click({ force: true });
14+
cy.wait(1000);
15+
cy.get('input[id="rsc-server"]').clear().type('http://connect:3939');
16+
cy.get('input[id="rsc-api-key"]').clear().type(Cypress.env('api_key'));
17+
cy.get('input[id="rsc-servername"]').clear().type('localhost');
18+
cy.get('a[class="btn btn-primary"]').contains(' Add Server').click();
19+
cy.wait(1000);
20+
cy.get('span[class="help-block"]').should('not.have.text',"Unable to verify");
21+
});
22+
it('Publish Content', () => {
23+
cy.visit('http://client:9999/tree/integration-testing/content/notebook/stock-report-jupyter.ipynb');
24+
cy.wait(1000);
25+
cy.get('a[id="publish-to-connect"]').click({ force: true });
26+
cy.wait(1000);
27+
cy.get('button[id="rsc-add-files"]').click();
28+
cy.wait(1000);
29+
cy.get('input[name="quandl-wiki-tsla.json.gz"]').click();
30+
cy.wait(1000);
31+
cy.get('button[id="add-files-dialog-accept"]').click();
32+
cy.wait(1000);
33+
cy.get('li[class="list-group-item"]').first().should('have.text'," quandl-wiki-tsla.json.gz");
34+
cy.wait(1000);
35+
cy.get('a[class="btn btn-primary"]').last().should('have.text',"Publish").click({ force: true });
36+
cy.wait(1000);
37+
cy.get('input[name="location"]').first().click();
38+
cy.wait(1000);
39+
cy.get('a[class="btn btn-primary"]').last().should('have.text',"Next").click();
40+
cy.wait(1000);
41+
cy.get('a[class="btn btn-primary"]').last().should('have.text',"Publish").click();
42+
cy.wait(1000);
43+
// allow for 5 minutes to deploy content
44+
cy.get('span[class="fa fa-link"]', { timeout: 300000 }).last().should('have.text'," Successfully published content").click();
45+
});
46+
it('Vist Content in Connect', () => {
47+
cy.connectLogin();
48+
cy.visit('http://connect:3939');
49+
cy.get('div[class="content-table__display-name"]').first().contains('stock-report-jupyter').click();
50+
cy.contentiFrame().contains('Stock Report: TSLA');
51+
});
52+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// ***********************************************************
2+
// This example plugins/index.js can be used to load plugins
3+
//
4+
// You can change the location of this file or turn off loading
5+
// the plugins file with the 'pluginsFile' configuration option.
6+
//
7+
// You can read more here:
8+
// https://on.cypress.io/plugins-guide
9+
// ***********************************************************
10+
11+
// This function is called when a project is opened or re-opened (e.g. due to
12+
// the project's config changing)
13+
14+
module.exports = (on, config) => {
15+
// `on` is used to hook into various events Cypress emits
16+
// `config` is the resolved Cypress config
17+
}

0 commit comments

Comments
 (0)