Skip to content

Commit d0cec93

Browse files
style: lint code
1 parent 4dc48b5 commit d0cec93

File tree

13 files changed

+4326
-1063
lines changed

13 files changed

+4326
-1063
lines changed

.commitlintrc.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": ["@commitlint/config-conventional"],
3+
"rules": {
4+
"body-max-line-length": [1, "always", 100],
5+
"footer-max-line-length": [1, "always", 100]
6+
}
7+
}

.husky/commit-msg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
npx commitlint --edit $1

.husky/pre-commit

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
npm run lint:tsc
2+
npx lint-staged

.lintstagedrc.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"*.{js,mjs,ts}": "eslint --fix",
3+
"*.{css,json,md,yml}": "prettier --write"
4+
}

.prettierrc.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"singleQuote": true
3+
}

cypress.config.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { defineConfig } from "cypress";
1+
import { defineConfig } from 'cypress';
22

33
export default defineConfig({
4+
// don't block CORS for LLM request
5+
chromeWebSecurity: false,
6+
47
e2e: {
5-
setupNodeEvents(on, config) {
8+
setupNodeEvents() {
69
// implement node event listeners here
710
},
811
},
9-
10-
// don't block CORS for LLM request
11-
chromeWebSecurity: false,
1212
});

cypress/e2e/home.cy.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
describe('template spec', () => {
22
it('passes', () => {
3-
cy.ai('go to example.cypress.io and see heading "Kitchen Sink"')
4-
cy.ai('click on "Commands" nav dropdown and click on link "Actions"')
5-
cy.ai('find label "Coupon Code" and type "HALFOFF" in text field')
6-
cy.ai('click button "Submit"')
7-
})
8-
})
3+
cy.ai('go to example.cypress.io and see heading "Kitchen Sink"');
4+
cy.ai('click on "Commands" nav dropdown and click on link "Actions"');
5+
cy.ai('find label "Coupon Code" and type "HALFOFF" in text field');
6+
cy.ai('click button "Submit"');
7+
});
8+
});

cypress/support/commands.ts

Lines changed: 60 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@
3636
// }
3737
// }
3838

39-
import { Ollama } from '@langchain/ollama'
40-
import { PromptTemplate } from '@langchain/core/prompts'
41-
import { resolve } from 'path'
42-
import { sanitize } from 'dompurify'
39+
import { PromptTemplate } from '@langchain/core/prompts';
40+
import { Ollama } from '@langchain/ollama';
41+
import { sanitize } from 'dompurify';
42+
import { resolve } from 'path';
4343

4444
const llm = new Ollama({
4545
model: 'qwen2.5-coder',
4646
numCtx: 16384, // truncating input prompt limit=4096
47-
})
47+
});
4848

4949
const template = `
5050
You're a QA engineer writing an E2E test step with Cypress
@@ -62,93 +62,93 @@ DOM:
6262
\`\`\`html
6363
{html}
6464
\`\`\`
65-
`
65+
`;
6666

67-
const prompt = PromptTemplate.fromTemplate(template.trim())
68-
const chain = prompt.pipe(llm)
67+
const prompt = PromptTemplate.fromTemplate(template.trim());
68+
const chain = prompt.pipe(llm);
6969

7070
function minutesToMilliseconds(minutes: number) {
71-
return 1000 * 60 * minutes
71+
return 1000 * 60 * minutes;
7272
}
7373

7474
function getGeneratedFilePath(): string {
75-
return resolve(Cypress.spec.absolute, `../__generated__/${Cypress.spec.name}.json`)
75+
return resolve(
76+
Cypress.spec.absolute,
77+
`../__generated__/${Cypress.spec.name}.json`,
78+
);
7679
}
7780

78-
const noop = () => {}
81+
const noop = () => {};
7982

8083
function readGeneratedFile() {
81-
return cy.readFile(getGeneratedFilePath(), { log: false }).should(noop)
84+
return cy.readFile(getGeneratedFilePath(), { log: false }).should(noop);
8285
}
8386

8487
function getTestKey(): string {
85-
return Cypress.currentTest.titlePath.join(' ')
88+
return Cypress.currentTest.titlePath.join(' ');
8689
}
8790

8891
function saveGeneratedCode(task: string, code: string) {
8992
readGeneratedFile().then((contents) => {
90-
contents = contents || {}
93+
contents = contents || {};
9194

92-
const key = getTestKey()
93-
contents[key] = contents[key] || {}
94-
contents[key][task] = code
95+
const key = getTestKey();
96+
contents[key] = contents[key] || {};
97+
contents[key][task] = code;
9598

96-
cy.writeFile(getGeneratedFilePath(), JSON.stringify(contents, null, 2), { log: false })
97-
})
99+
cy.writeFile(getGeneratedFilePath(), JSON.stringify(contents, null, 2), {
100+
log: false,
101+
});
102+
});
98103
}
99104

100-
function getGeneratedCode(task: string) {
101-
return readGeneratedFile().then((json) => {
102-
try {
103-
return json[getTestKey()][task]
104-
} catch (error) {
105-
return ''
106-
}
107-
})
108-
}
109-
110-
Cypress.Commands.add('ai', (task, options) => {
111-
Cypress.log({ displayName: 'ai', message: task })
105+
Cypress.Commands.add('ai', (task) => {
106+
Cypress.log({ displayName: 'ai', message: task });
112107

113108
return readGeneratedFile().then((json) => {
114109
try {
115-
const code = json[getTestKey()][task]
116-
117-
if (code) {
118-
return eval(code)
119-
}
120-
} catch (error) {
121-
// pass
122-
}
123-
124-
cy.document({ log: false }).then({ timeout: minutesToMilliseconds(2) }, async (doc) => {
125-
const response = await chain.invoke({
126-
task,
127-
// html: sanitize(doc.documentElement.outerHTML),
128-
html: sanitize(doc.body.innerHTML),
129-
})
130-
// console.log(response)
131-
132-
const error = "I'm sorry, but I can't assist with that request."
133-
if (response.includes(error)) {
134-
throw new Error(error)
135-
}
110+
const code = json[getTestKey()][task];
136111

137-
const code = response.match(/```(javascript|js)?([\s\S]+?)```/)?.[2]?.trim()
138112
if (code) {
139-
eval(code)
140-
saveGeneratedCode(task, code)
113+
return eval(code);
141114
}
142-
})
143-
})
144-
})
115+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, no-empty
116+
} catch (error) {}
117+
118+
cy.document({ log: false }).then(
119+
{ timeout: minutesToMilliseconds(2) },
120+
async (doc) => {
121+
const response = await chain.invoke({
122+
task,
123+
// html: sanitize(doc.documentElement.outerHTML),
124+
html: sanitize(doc.body.innerHTML),
125+
});
126+
// console.log(response)
127+
128+
const error = "I'm sorry, but I can't assist with that request.";
129+
if (response.includes(error)) {
130+
throw new Error(error);
131+
}
132+
133+
const code = response
134+
.match(/```(javascript|js)?([\s\S]+?)```/)?.[2]
135+
?.trim();
136+
if (code) {
137+
eval(code);
138+
saveGeneratedCode(task, code);
139+
}
140+
},
141+
);
142+
});
143+
});
145144

146145
declare global {
146+
// eslint-disable-next-line @typescript-eslint/no-namespace
147147
namespace Cypress {
148148
interface Chainable {
149-
ai(task: string, options?: object): Chainable<void>
149+
ai(task: string): Chainable<void>;
150150
}
151151
}
152152
}
153153

154-
export {}
154+
export {};

cypress/support/e2e.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@
1414
// ***********************************************************
1515

1616
// Import commands.js using ES2015 syntax:
17-
import './commands'
17+
import './commands';

eslint.config.mjs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import path from 'node:path';
2+
import { fileURLToPath } from 'node:url';
3+
4+
import { includeIgnoreFile } from '@eslint/compat';
5+
import { FlatCompat } from '@eslint/eslintrc';
6+
import js from '@eslint/js';
7+
import typescriptEslint from '@typescript-eslint/eslint-plugin';
8+
import tsParser from '@typescript-eslint/parser';
9+
import prettier from 'eslint-plugin-prettier';
10+
import simpleImportSort from 'eslint-plugin-simple-import-sort';
11+
import tsdoc from 'eslint-plugin-tsdoc';
12+
import globals from 'globals';
13+
14+
const __filename = fileURLToPath(import.meta.url);
15+
const __dirname = path.dirname(__filename);
16+
const gitignorePath = path.resolve(__dirname, '.gitignore');
17+
18+
const compat = new FlatCompat({
19+
baseDirectory: __dirname,
20+
recommendedConfig: js.configs.recommended,
21+
allConfig: js.configs.all,
22+
});
23+
24+
export default [
25+
includeIgnoreFile(gitignorePath),
26+
27+
...compat.extends(
28+
'eslint:recommended',
29+
'plugin:@typescript-eslint/recommended',
30+
),
31+
32+
{
33+
files: ['**/*.js', '**/*.mjs', '**/*.ts', '**/*.tsx'],
34+
35+
plugins: {
36+
'@typescript-eslint': typescriptEslint,
37+
prettier,
38+
'simple-import-sort': simpleImportSort,
39+
tsdoc,
40+
},
41+
42+
languageOptions: {
43+
globals: {
44+
...globals.node,
45+
},
46+
parser: tsParser,
47+
},
48+
49+
rules: {
50+
'@typescript-eslint/no-extra-semi': 'off',
51+
'@typescript-eslint/no-unused-vars': 'error',
52+
'no-console': 'error',
53+
'no-debugger': 'error',
54+
'prettier/prettier': 'error',
55+
'simple-import-sort/exports': 'error',
56+
'simple-import-sort/imports': 'error',
57+
'tsdoc/syntax': 'error',
58+
},
59+
},
60+
];

0 commit comments

Comments
 (0)