# Test Automation

CloudIO Platform comes with an inbuilt test automation framework. You can create test scripts to automate the testing of both backend services & frontend UI interactions. Test scripts are written in JavaScript and can be auto-generated via. recording.

<figure><img src="/files/1MBfg6GrAnffn3IdcmR4" alt=""><figcaption><p>Test Automcation In Action</p></figcaption></figure>

The test scripts are similar to Jest with chaijs assertions.

{% code title="Sample Backend Test Script" overflow="wrap" lineNumbers="true" %}

```javascript
/* refer https://www.chaijs.com/api/bdd/ for more assertions */

beforeAll(async () => {
    platform.showInfo("Before all...");
});

afterAll(async () => {
    platform.showInfo("After all...");
});

beforeEach(async () => {
    platform.showInfo("Before each...");
});

afterEach(async () => {
    platform.showInfo("After each...");
});

test("Query Test", async () => {
    // const rows = await find('Todos', { "filter": [], "limit": 2000, "offset": 0, "sort": { "id": 1 } });
    // expect(rows.length).to.gt(0);
    expect(1 + 1).to.eq(2);
});

test("Insert Test", async () => {
    // const input = [{ "completed": "N", "fileUid": "01G2T3JJAREESW47ZYTHX43ZPG", "todo": "test test" }];
    // const rows = await insertMany('Todos', input);
    // expect(rows[0].lastUpdateDate).to.not.empty;
    expect(1 + 1).to.eq(2);
});

test("Dummy Test", async () => {
    // refer https://www.chaijs.com/api/bdd/ for more assertions
    expect(1 + 1).to.eq(2);
});

/*
Find below the typescript definition for all the inbuilt functions available along with the standard ES2020 JavaScript


    import { WSRequest, WSSuccessResponse, AllDatasources, Query, DBRow } from '@cloudio-saas/datasource-types';
    import { Platform, UIDriver, MultiPostFunction, SinglePostFunction, TestFn, FnWithResult, FnWithResults, TestResult, SQLResult } from 'cloudio';
    type DataSourceName = keyof AllDatasources;
    declare global {
      const platform: Platform;    
      const ui: UIDriver;
      const expect: Chai.ExpectStatic;
      declare function test(name: string, fn: TestFn): void;
      declare function beforeAll(fn: TestFn): void;
      declare function afterAll(fn: FnWithResults): void;
      declare function beforeEach(fn: TestFn): void;
      declare function afterEach(fn: FnWithResult): void;
      declare function post(request: WSRequest, appUid: string): Promise<WSSuccessResponse<any>>;
      declare function find<T extends DataSourceName>(ds: T, request: Query<AllDatasources[T]>): Promise<DBRow<AllDatasources[T]>[]>;      
      const insertMany = MultiPostFunction;
      const updateMany = MultiPostFunction;
      const deleteMany = MultiPostFunction;
      const insertOne = SinglePostFunction;
      const updateOne = SinglePostFunction;
      const deleteOne = SinglePostFunction;
      declare function executeQuery(sql: string): Promise<SQLType>;
      declare function executeUpdate(sql: string): Promise<SQLType>;
    }

*/

```

{% endcode %}

{% code title="Sample Frontend Test Script" overflow="wrap" lineNumbers="true" %}

```
/* refer https://www.chaijs.com/api/bdd/ for more assertions */

beforeAll(async () => {
    platform.showInfo("Before all...");
});

afterAll(async () => {
    platform.showInfo("After all...");
});

beforeEach(async () => {
    platform.showInfo("Before each...");
});

afterEach(async () => {
    platform.showInfo("After each...");
});

test("Sample UI Test", async () => {
  
  // To navigate to a page
  await ui.page('automation');
  
  // To select a tab item and ignore if it's already selected
  await ui.click('tabItem1', { skipActive: true });
  
  // To sort a column in a data grid
  await ui.gridColumnSort('stringColumn2', { direction: 'asc' });
  
  // To click a button, box, link, etc
  await ui.click('button1');
  
  // To type a text value in a string column on the 2nd row of a data grid
  await ui.type('stringColumn2', 'test', { row: 2 });
  
  // To type a number value in a number column on the 1st row of a data grid
  await ui.type('numberColumn1', 123);
  
  // To type a date value in a date column on the 1st row of a data grid
  await ui.type('dateColumn2', new Date());

  // To check a checkbox on the 1st row of a data grid
  await ui.click("checkboxColumn");

  // To group commands to be performed within a scope e.g. popup
  await ui.scope("popup", async () => {
    // These itemId's are relative to the scope's itemId
    await ui.type('select', 'XYZ');
    await ui.closePopup("popup");
  });

  // To select an option in a radio box by value (not label)
  await ui.type('radioBox', "Y");

  // To type a number value in a number column's header filter of a data grid
  await ui.typeGridHeaderFilter('numberColumn1', '123');

  // To type a smart search number filter
  await ui.typeSmartSearchFilter('smartSearch', 'Number', 'greater than', 123);

  // To check if a notification is displayed with a given message and close it
  await ui.hasNotified('Button clicked!').then(ui.close);

  // To wait for 10 seconds
  await ui.wait(10000);

  // To click any item with data-testid attribute or with a specific selector
  await ui.click({testid: 'search-entries'});

});

/*
Find below the typescript definition for all the inbuilt functions available along with the standard ES2020 JavaScript


    import { WSRequest, WSSuccessResponse, AllDatasources, Query, DBRow } from '@cloudio-saas/datasource-types';
    import { Platform, UIDriver, MultiPostFunction, SinglePostFunction, TestFn, FnWithResult, FnWithResults, TestResult, SQLResult } from 'cloudio';
    type DataSourceName = keyof AllDatasources;
    declare global {
      const platform: Platform;    
      const ui: UIDriver;
      const expect: Chai.ExpectStatic;
      declare function test(name: string, fn: TestFn): void;
      declare function beforeAll(fn: TestFn): void;
      declare function afterAll(fn: FnWithResults): void;
      declare function beforeEach(fn: TestFn): void;
      declare function afterEach(fn: FnWithResult): void;
      declare function post(request: WSRequest, appUid: string): Promise<WSSuccessResponse<any>>;
      declare function find<T extends DataSourceName>(ds: T, request: Query<AllDatasources[T]>): Promise<DBRow<AllDatasources[T]>[]>;      
      const insertMany = MultiPostFunction;
      const updateMany = MultiPostFunction;
      const deleteMany = MultiPostFunction;
      const insertOne = SinglePostFunction;
      const updateOne = SinglePostFunction;
      const deleteOne = SinglePostFunction;
      declare function executeQuery(sql: string): Promise<SQLType>;
      declare function executeUpdate(sql: string): Promise<SQLType>;
    }

*/

```

{% endcode %}

With the record option, you can generate test scripts while navigating through the application flow. Once generated, you can further finetune the script as needed.

<figure><img src="/files/goUbDmvTVnRgeLRvwzIY" alt=""><figcaption><p>Test Scripts Sidebar Tab</p></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://next-docs.cloudio.io/app-deployment/test-automation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
