From 3b44fd68486b5af092ca391cf5df22a10ae6799b Mon Sep 17 00:00:00 2001 From: lironsh Date: Thu, 9 Jan 2025 15:29:38 +0200 Subject: [PATCH] chore: add a check in the `PromptCreator` constructor to merge redundant categories in the API catalog due to the fact is that a merge like this happens when we extend the API, and to maintain consistency. --- src/test-utils/APICatalogTestUtils.ts | 63 ++++++++ src/utils/PromptCreator.ts | 26 ++-- .../__snapshots__/PromptCreator.test.ts.snap | 140 ++++++++++++++++++ 3 files changed, 219 insertions(+), 10 deletions(-) diff --git a/src/test-utils/APICatalogTestUtils.ts b/src/test-utils/APICatalogTestUtils.ts index 2eefe69..dd8a73d 100644 --- a/src/test-utils/APICatalogTestUtils.ts +++ b/src/test-utils/APICatalogTestUtils.ts @@ -1,3 +1,5 @@ +import {TestingFrameworkAPICatalog} from "@/types"; + export const bazCategory = { title: 'Custom Actions', items: [ @@ -37,3 +39,64 @@ export const barCategory2 = { export const dummyContext = {foo: jest.fn()}; export const dummyBarContext1 = {bar: jest.fn()}; export const dummyBarContext2 = {bar: jest.fn()}; + +export const promptCreatorConstructorMockAPI: TestingFrameworkAPICatalog = { + context: {}, + categories: [ + { + title: 'Actions', + items: [{ + signature: 'tap(element: Element)', + description: 'Taps on the specified element.', + example: 'await element(by.id("button")).tap();', + guidelines: ['Ensure the element is tappable before using this method.'] + }, + { + signature: 'typeText(element: Element, text: string)', + description: 'Types the specified text into the element.', + example: 'await element(by.id("input")).typeText("Hello, World!");', + guidelines: ['Use this method only on text input elements.'] + }] + }, + { + title: 'Assertions', + items: [{ + signature: 'toBeVisible()', + description: 'Asserts that the element is visible on the screen.', + example: 'await expect(element(by.id("title"))).toBeVisible();', + guidelines: ['Consider scroll position when using this assertion.'] + }] + }, + { + title: 'Assertions', + items: [{ + signature: 'toBeEnabled()', + description: 'Asserts that the element is enabled and can be interacted with.', + example: 'await expect(element(by.id("submitButton"))).toBeEnabled();', + guidelines: ['Ensure that the element is not disabled before performing actions.'] + }] + }, + { + title: 'Matchers', + items: [ + { + signature: 'by.id(id: string)', + description: 'Matches elements by their ID attribute.', + example: 'element(by.id("uniqueId"))', + guidelines: ['Use unique IDs for elements to avoid conflicts, combine with atIndex() if necessary.'] + } + ] + }, + { + title: 'Actions', + items: [ + { + signature: 'swipe(direction: string)', + description: 'Swipes in the specified direction.', + example: 'await swipe("up");', + guidelines: ['Use this method to scroll the screen.'] + } + ] + } + ] +}; diff --git a/src/utils/PromptCreator.ts b/src/utils/PromptCreator.ts index 4802fbd..86c0a19 100644 --- a/src/utils/PromptCreator.ts +++ b/src/utils/PromptCreator.ts @@ -7,24 +7,30 @@ import { export class PromptCreator { constructor(private apiCatalog: TestingFrameworkAPICatalog) { + this.apiCatalog.categories = this.mergeCategories(this.apiCatalog.categories); } extendAPICategories( - newCategories: TestingFrameworkAPICatalogCategory[] | TestingFrameworkAPICatalogCategory + newCategories: TestingFrameworkAPICatalogCategory[] ): void { - const categories = Array.isArray(newCategories) ? newCategories : [newCategories]; + this.apiCatalog.categories = this.mergeCategories([...this.apiCatalog.categories, ...newCategories]); + } - categories.forEach((category) => { - const existingCategory = this.apiCatalog.categories.find( - (c) => c.title === category.title - ); + private mergeCategories(categories: TestingFrameworkAPICatalogCategory[]): TestingFrameworkAPICatalogCategory[] { + return categories.reduce((mergedCategories, category) => { + const existingIndex = mergedCategories.findIndex(c => c.title === category.title); - if (existingCategory) { - existingCategory.items.push(...category.items); + const uniqueItems = (items: TestingFrameworkAPICatalogItem[]) => Array.from(new Set(items)); + + if (existingIndex >= 0) { + mergedCategories[existingIndex].items = uniqueItems([...mergedCategories[existingIndex].items, ...category.items]); + return mergedCategories; } else { - this.apiCatalog.categories.push(category); + category.items = uniqueItems(category.items); } - }); + + return [...mergedCategories, {...category}]; + }, [] as TestingFrameworkAPICatalogCategory[]); } createPrompt( diff --git a/src/utils/__snapshots__/PromptCreator.test.ts.snap b/src/utils/__snapshots__/PromptCreator.test.ts.snap index f6f2789..8f8afa8 100644 --- a/src/utils/__snapshots__/PromptCreator.test.ts.snap +++ b/src/utils/__snapshots__/PromptCreator.test.ts.snap @@ -1,5 +1,145 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`PromptCreator constructor should merge redundant categories 1`] = ` +"# Test Code Generation + +You are an AI assistant tasked with generating test code for an application using the provided UI testing framework API. +Please generate the minimal executable code to perform the desired intent based on the given information and context. + +## Context + +### Intent to perform + +Generate the minimal executable code to perform the following intent: "expect button to be visible" + +### View hierarchy + +\`\`\` +