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

fix(AI): AI is not triggered #4422

Merged
merged 3 commits into from
Jul 27, 2024
Merged
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
4 changes: 2 additions & 2 deletions docs/helpers/AI.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ title: AI
AI Helper for CodeceptJS.

This helper class provides integration with the AI GPT-3.5 or 4 language model for generating responses to questions or prompts within the context of web pages. It allows you to interact with the GPT-3.5 model to obtain intelligent responses based on HTML fragments or general prompts.
This helper should be enabled with any web helpers like Playwright or Puppeteer or WebDrvier to ensure the HTML context is available.
This helper should be enabled with any web helpers like Playwright or Puppeteer or WebDriver to ensure the HTML context is available.

Use it only in development mode. It is recommended to run it only inside pause() mode.

## Configuration

This helper should be configured in codecept.json or codecept.conf.js
This helper should be configured in codecept.conf.{js|ts}

- `chunkSize`: - The maximum number of characters to send to the AI API at once. We split HTML fragments by 8000 chars to not exceed token limit. Increase this value if you use GPT-4.

Expand Down
76 changes: 43 additions & 33 deletions lib/helper/AI.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@ const { beautify } = require('../utils')
const output = require('../output')
const { registerVariable } = require('../pause')

const gtpRole = {
user: 'user',
}

/**
* AI Helper for CodeceptJS.
*
* This helper class provides integration with the AI GPT-3.5 or 4 language model for generating responses to questions or prompts within the context of web pages. It allows you to interact with the GPT-3.5 model to obtain intelligent responses based on HTML fragments or general prompts.
* This helper should be enabled with any web helpers like Playwright or Puppeteer or WebDrvier to ensure the HTML context is available.
* This helper should be enabled with any web helpers like Playwright or Puppeteer or WebDriver to ensure the HTML context is available.
*
* Use it only in development mode. It is recommended to run it only inside pause() mode.
*
* ## Configuration
*
* This helper should be configured in codecept.json or codecept.conf.js
* This helper should be configured in codecept.conf.{js|ts}
*
* * `chunkSize`: (optional, default: 80000) - The maximum number of characters to send to the AI API at once. We split HTML fragments by 8000 chars to not exceed token limit. Increase this value if you use GPT-4.
*/
Expand All @@ -33,6 +37,7 @@ class AI extends Helper {
chunkSize: 80000,
}
this.options = { ...this.options, ...config }
this.aiAssistant.enable(this.config)
}

_beforeSuite() {
Expand Down Expand Up @@ -68,8 +73,8 @@ class AI extends Helper {

for (const chunk of htmlChunks) {
const messages = [
{ role: 'user', content: prompt },
{ role: 'user', content: `Within this HTML: ${minifyHtml(chunk)}` },
{ role: gtpRole.user, content: prompt },
{ role: gtpRole.user, content: `Within this HTML: ${minifyHtml(chunk)}` },
]

if (htmlChunks.length > 1)
Expand Down Expand Up @@ -104,8 +109,8 @@ class AI extends Helper {
const html = await this.helper.grabHTMLFrom(locator)

const messages = [
{ role: 'user', content: prompt },
{ role: 'user', content: `Within this HTML: ${minifyHtml(html)}` },
{ role: gtpRole.user, content: prompt },
{ role: gtpRole.user, content: `Within this HTML: ${minifyHtml(html)}` },
]

const response = await this._processAIRequest(messages)
Expand All @@ -121,7 +126,7 @@ class AI extends Helper {
* @returns {Promise<string>} - A Promise that resolves to the generated response from the GPT model.
*/
async askGptGeneralPrompt(prompt) {
const messages = [{ role: 'user', content: prompt }]
const messages = [{ role: gtpRole.user, content: prompt }]

const response = await this._processAIRequest(messages)

Expand Down Expand Up @@ -156,40 +161,45 @@ class AI extends Helper {
* @returns {Promise<Object>} A promise that resolves to the requested page object.
*/
async askForPageObject(pageName, extraPrompt = null, locator = null) {
const html = locator ? await this.helper.grabHTMLFrom(locator) : await this.helper.grabSource()

const spinner = ora(' Processing AI request...').start()
await this.aiAssistant.setHtmlContext(html)
const response = await this.aiAssistant.generatePageObject(extraPrompt, locator)
spinner.stop()

if (!response[0]) {
output.error('No response from AI')
return ''
}
try {
const html = locator ? await this.helper.grabHTMLFrom(locator) : await this.helper.grabSource()
await this.aiAssistant.setHtmlContext(html)
const response = await this.aiAssistant.generatePageObject(extraPrompt, locator)
spinner.stop()

if (!response[0]) {
output.error('No response from AI')
return ''
}

const code = beautify(response[0])
const code = beautify(response[0])

output.print('----- Generated PageObject ----')
output.print(code)
output.print('-------------------------------')
output.print('----- Generated PageObject ----')
output.print(code)
output.print('-------------------------------')

const fileName = path.join(output_dir, `${pageName}Page-${Date.now()}.js`)
const fileName = path.join(output_dir, `${pageName}Page-${Date.now()}.js`)

output.print(output.styles.bold(`Page object for ${pageName} is saved to ${output.styles.bold(fileName)}`))
fs.writeFileSync(fileName, code)
output.print(output.styles.bold(`Page object for ${pageName} is saved to ${output.styles.bold(fileName)}`))
fs.writeFileSync(fileName, code)

try {
registerVariable('page', require(fileName))
output.success('Page object registered for this session as `page` variable')
output.print('Use `=>page.methodName()` in shell to run methods of page object')
output.print('Use `click(page.locatorName)` to check locators of page object')
} catch (err) {
output.error('Error while registering page object')
output.error(err.message)
}
try {
registerVariable('page', require(fileName))
output.success('Page object registered for this session as `page` variable')
output.print('Use `=>page.methodName()` in shell to run methods of page object')
output.print('Use `click(page.locatorName)` to check locators of page object')
} catch (err) {
output.error('Error while registering page object')
output.error(err.message)
}

return code
return code
} catch (e) {
spinner.stop()
throw Error(`Something went wrong! ${e.message}`)
}
}

async _processAIRequest(messages) {
Expand Down
Loading