From e5fd64f8013dd77c188c7b073ae9a925f95d192a Mon Sep 17 00:00:00 2001 From: Filip Pospisil Date: Mon, 18 Dec 2023 10:41:33 +0100 Subject: [PATCH] FUSETOOLS2-2201 --- .github/workflows/productized.yaml | 175 +++++ .../tests/00_set.camel.version.test.ts | 72 ++ src/ui-test/tests/camel.settings.test.ts | 13 +- src/ui-test/tests/dsls.test.dev.ts | 642 ++++++++++++++++++ .../tests/xx_check.camel.version.test.ts | 31 + src/ui-test/utils/testUtils.ts | 25 + 6 files changed, 956 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/productized.yaml create mode 100644 src/ui-test/tests/00_set.camel.version.test.ts create mode 100644 src/ui-test/tests/dsls.test.dev.ts create mode 100644 src/ui-test/tests/xx_check.camel.version.test.ts diff --git a/.github/workflows/productized.yaml b/.github/workflows/productized.yaml new file mode 100644 index 000000000..66ef0bc30 --- /dev/null +++ b/.github/workflows/productized.yaml @@ -0,0 +1,175 @@ +name: Productized CI + +on: + push: + branches: [ main, FUSETOOLS2-2201 ] + pull_request: + branches: [ main ] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true + +jobs: + main: + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest, macos-13, windows-latest ] + version: [ max ] # [ "x.x.x" | latest | max ] + type: [ stable ] # [ stable | insider ] + camelversion: [ "4.0.0", "4.0.0.redhat-00031"] + + env: + CODE_VERSION: ${{ matrix.version }} + CODE_TYPE: ${{ matrix.type }} + TEST_RESOURCES: test-resources + CAMEL_VERSION: ${{ matrix.camelversion }} + + runs-on: ${{ matrix.os }} + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: "temurin" + + - name: Test java + run: java --version + + - name: Install JBang (ubuntu, macOS) + if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-13' + run: | + curl -Ls https://sh.jbang.dev | bash -s - app setup + echo "$HOME/.jbang/bin" >> $GITHUB_PATH + + - name: Install JBang (windows) + if: matrix.os == 'windows-latest' + run: choco install jbang + + - name: Setup JBang (trusted sources) + run: jbang trust add https://github.com/apache/ + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 18.15.x + cache: npm + + - name: Setup vsce + run: | + npm install -g typescript @vscode/vsce + vsce --version + + - name: npm-ci + run: npm ci + + - name: npm-vscode:prepublish + run: npm run vscode:prepublish + + - name: test (ubuntu) + id: test_Ubuntu + if: matrix.os == 'ubuntu-latest' + run: xvfb-run --auto-servernum npm test + + - name: test (macos, windows) + if: matrix.os != 'ubuntu-latest' + run: npm test + + - name: ui test (ubuntu) + id: uiTest_Ubuntu + if: matrix.os == 'ubuntu-latest' + run: xvfb-run --auto-servernum npm run ui-test + + - name: ui test (macos, windows) + id: uiTest_MacOS_Windows + if: matrix.os != 'ubuntu-latest' + run: npm run ui-test + + - name: vsce-package + run: vsce package + + - name: get-npm-version + id: package-version + if: matrix.os == 'ubuntu-latest' + uses: martinbeentjes/npm-get-version-action@v1.3.1 + + - name: Generate SBOM + if: matrix.os == 'ubuntu-latest' + run: | + npm install --global @cyclonedx/cyclonedx-npm + cyclonedx-npm --omit dev --output-file node-sbom.json + wget https://github.com/CycloneDX/cyclonedx-cli/releases/download/v0.25.0/cyclonedx-linux-x64 + chmod +x cyclonedx-linux-x64 + ./cyclonedx-linux-x64 merge --hierarchical --group com.github.camel-tooling --name vscode-apache-camel --version ${{ steps.package-version.outputs.current-version}} --input-files node-sbom.json camel-ls-sbom.json --output-file manifest.json + + - name: Store SBOM + uses: actions/upload-artifact@v3 + if: matrix.os == 'ubuntu-latest' + with: + name: sbom + path: manifest.json + - name: Store Camel Language Server log + uses: actions/upload-artifact@v3 + if: failure() && matrix.os != 'windows-latest' + with: + name: ${{ matrix.os }}-${{ matrix.version }}-camel-lsp-log + path: | + /tmp/log-camel-lsp.log + /tmp/log-camel*.log.gz + - name: Store VS Code Logs + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.os }}-${{ matrix.version }}-test-logs + path: .vscode-test/logs/* + + - name: Store UI test log + uses: actions/upload-artifact@v3 + if: | + (failure() || cancelled()) && + (steps.uiTest_Ubuntu.outcome == 'failure' || + steps.uiTest_MacOS_Windows.outcome == 'failure' || + steps.uiTest_Ubuntu.outcome == 'cancelled' || + steps.uiTest_MacOS_Windows.outcome == 'cancelled') + with: + name: ${{ matrix.os }}-${{ matrix.version }}-ui-test-logs + path: test-resources/settings/logs/* + + - name: Store UI Test Screenshots + uses: actions/upload-artifact@v3 + if: | + (failure() || cancelled()) && + (steps.uiTest_Ubuntu.outcome == 'failure' || + steps.uiTest_MacOS_Windows.outcome == 'failure' || + steps.uiTest_Ubuntu.outcome == 'cancelled' || + steps.uiTest_MacOS_Windows.outcome == 'cancelled') + with: + name: ${{ matrix.os }}-${{ matrix.version }}-ui-test-screenshots + path: test-resources/screenshots/*.png + + check: + if: always() + runs-on: ubuntu-latest + name: Status Check + needs: [ main ] + steps: + - name: Test Matrix Result + run: | + echo result = ${{ needs.main.result }} + - name: Status Check - success + if: ${{ needs.main.result == 'success' }} + run: | + echo "All tests successfully completed!" + exit 0 + - name: Status Check - failure + if: ${{ needs.main.result != 'success' }} + run: | + echo "Status Check failed!" + exit 1 diff --git a/src/ui-test/tests/00_set.camel.version.test.ts b/src/ui-test/tests/00_set.camel.version.test.ts new file mode 100644 index 000000000..b056d81c7 --- /dev/null +++ b/src/ui-test/tests/00_set.camel.version.test.ts @@ -0,0 +1,72 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License", destination); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//import { assert } from 'chai'; +import { + CATALOG_VERSION_ID, + CATALOG_VERSION_UI, + RESOURCES, + closeEditor, + readUserSetting, + waitUntilExtensionIsActivated +} from '../utils/testUtils'; +import { + ActivityBar, + before, + VSBrowser, + WebDriver, + TextSetting, + Workbench +} from 'vscode-uitests-tooling'; +import * as pjson from '../../../package.json'; +import { assert } from 'chai'; + +describe('set camel version', function () { + this.timeout(150000); + + let driver: WebDriver; + + before(async function () { + this.timeout(40000); + driver = VSBrowser.instance.driver; + await VSBrowser.instance.openResources(RESOURCES); + await VSBrowser.instance.waitForWorkbench(); + + await waitUntilExtensionIsActivated(driver, `${pjson.displayName}`); + await (await new ActivityBar().getViewControl('Explorer')).openView(); + }); + + it('set and check value', async function () { + + if(process.env.CAMEL_VERSION == null || process.env.CAMEL_VERSION.length == 0){ // no env variable set or is empty + this.skip(); + } + + // set version in ui + const settings = await new Workbench().openSettings(); + const textSetting = await settings.findSetting(CATALOG_VERSION_UI, 'Camel') as TextSetting; + await textSetting.setValue(process.env.CAMEL_VERSION); + await closeEditor('Settings', true); + + // wait until change is available in settings file + await driver.wait(async function () { + return readUserSetting(CATALOG_VERSION_ID) === (process.env.CAMEL_VERSION); + }, 15000, `Camel Version not set in time limit.`, 1500); + + assert.equal(readUserSetting(CATALOG_VERSION_ID), process.env.CAMEL_VERSION) + }); +}); diff --git a/src/ui-test/tests/camel.settings.test.ts b/src/ui-test/tests/camel.settings.test.ts index ef3dd91fa..222bd31bf 100644 --- a/src/ui-test/tests/camel.settings.test.ts +++ b/src/ui-test/tests/camel.settings.test.ts @@ -29,6 +29,7 @@ import { initXMLFileWithJBang, JBANG_VERSION_ID, killTerminal, + readUserSetting, resetUserSettings, RESOURCES, setAdditionalComponents, @@ -121,7 +122,15 @@ describe('User preferences', function () { after(async function () { await new EditorView().closeAllEditors(); - resetUserSettings(CATALOG_VERSION_ID); + if(process.env.CAMEL_VERSION != null){ + await setCamelCatalogVersion(process.env.CAMEL_VERSION); + await driver.wait(async function () { + return readUserSetting(CATALOG_VERSION_ID) === (process.env.CAMEL_VERSION); + }, 15000, `Camel Version not set in time limit.`, 1500); + + } else { + resetUserSettings(CATALOG_VERSION_ID); + } }); afterEach(async function () { @@ -270,4 +279,4 @@ describe('User preferences', function () { assert.equal(items.length, 0); } } -}); +}); \ No newline at end of file diff --git a/src/ui-test/tests/dsls.test.dev.ts b/src/ui-test/tests/dsls.test.dev.ts new file mode 100644 index 000000000..a8502072a --- /dev/null +++ b/src/ui-test/tests/dsls.test.dev.ts @@ -0,0 +1,642 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License", destination); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as path from 'path'; +import { assert } from 'chai'; +import { + ActivityBar, + BottomBarPanel, + ContentAssist, + DefaultTreeSection, + DefaultWait, + EditorView, + MarkerType, + SideBarView, + TextEditor, + VSBrowser, + WaitUntil, + WebDriver, + Workbench, + before +} from 'vscode-uitests-tooling'; +import * as ca from '../utils/contentAssist'; +import { + activateEditor, + CAMEL_CONTEXT_JAVA, + CAMEL_CONTEXT_XML, + CAMEL_CONTEXT_YAML, + CAMEL_ROUTE_XML, + clearReferences, + closeEditor, + getTextExt, + GROOVY_TESTFILE, + GROOVY_URI_LINE, + GROOVY_URI_POSITION, + isReferencesAvailable, + JAVA_URI_LINE, + JAVA_URI_POSITION, + JS_TESTFILE, + JS_URI_LINE, + JS_URI_POSITION, + KOTLIN_TESTFILE, + KOTLIN_URI_LINE, + KOTLIN_URI_POSITION, + openFileInEditor, + openProblemsView, + REFERENCES_FILE_1, + REFERENCES_FILE_2, + RESOURCES, + RESOURCES_REFERENCES, + waitUntilEditorIsOpened, + waitUntilExtensionIsActivated, + XML_URI_LINE, + XML_URI_POSITION, + YAML_URI_LINE, + YAML_URI_POSITION +} from '../utils/testUtils'; +import * as pjson from '../../../package.json'; + +describe('Language DSL support', function () { + + const DSL_TIMEOUT = 300000; + + let driver: WebDriver; + let contentAssist: ContentAssist; + let editor: TextEditor; + + const _setup = function (camel_file: string) { + return async function () { + this.timeout(20000); + await VSBrowser.instance.openResources(path.join(RESOURCES, camel_file)); + await waitUntilEditorIsOpened(driver, camel_file); + editor = await activateEditor(driver, camel_file); + } + }; + + const _clean = function (camel_file: string) { + return async function () { + this.timeout(15000); + await closeEditor(camel_file, false); + } + }; + + before(async function () { + this.timeout(90000); + driver = VSBrowser.instance.driver; + await VSBrowser.instance.openResources(RESOURCES); + await VSBrowser.instance.waitForWorkbench(); + + await waitUntilExtensionIsActivated(driver, `${pjson.displayName}`); + await (await new ActivityBar().getViewControl('Explorer')).openView(); + }); + + describe('XML DSL support', function () { + this.timeout(DSL_TIMEOUT); + + describe('Camel URI code completion', function () { + + before(_setup(CAMEL_CONTEXT_XML)); + after(_clean(CAMEL_CONTEXT_XML)); + + beforeEach(async function () { + await activateEditor(driver, CAMEL_CONTEXT_XML); + }); + + it('Open "camel-context.xml" file inside Editor View', async function () { + await openContextInsideEditorView(CAMEL_CONTEXT_XML); + }); + + it('Code completion is working for component schemes (the part before the ":")', async function () { + await codeCompletionForComponentScheme(XML_URI_LINE, XML_URI_POSITION, ''); + }); + + it('Code completion is working for endpoint options (the part after the "?")', async function () { + await codeCompletionForEndpointOptions(XML_URI_LINE, XML_URI_POSITION, ''); + }); + + it('Code completion is working for additional endpoint options (the part after "&")', async function () { + await codeCompletionForAdditionalEndpointOptions(XML_URI_LINE, XML_URI_POSITION, true, ''); + await codeCompletionForAdditionalEndpointOptionsValue(XML_URI_LINE, XML_URI_POSITION, true, ''); + }); + }); + + describe('Endpoint options filtering', function () { + + before(_setup(CAMEL_CONTEXT_XML)); + after(_clean(CAMEL_CONTEXT_XML)); + + beforeEach(async function () { + await activateEditor(driver, CAMEL_CONTEXT_XML); + }); + + it('Duplicate endpoint options are filtered out', async function () { + await duplicateEndpointOptionsFiltering(XML_URI_LINE, XML_URI_POSITION, true); + }); + }); + + describe('Diagnostics for Camel URIs', function () { + + before(_setup(CAMEL_CONTEXT_XML)); + after(_clean(CAMEL_CONTEXT_XML)); + + beforeEach(async function () { + await activateEditor(driver, CAMEL_CONTEXT_XML); + }); + + it('LSP diagnostics support for XML DSL', async function () { + await lspDiagnosticSupport(XML_URI_LINE, XML_URI_POSITION); + }); + }); + + describe('Auto-completion for referenced components IDs', function () { + + before(_setup(CAMEL_ROUTE_XML)); + after(_clean(CAMEL_ROUTE_XML)); + + beforeEach(async function () { + await activateEditor(driver, CAMEL_ROUTE_XML); + }); + + it('Auto-completion for referenced ID of "direct" component', async function () { + await autocompletionForReferenceIDofDirectComponent(6, 29, ''); + }); + + it('Auto-completion for referenced ID of "direct-vm" component', async function () { + await autocompletionForReferenceIDofDirectVMComponent(13, 30, ''); + }); + }); + + describe('Find references for direct and direct VM components', function () { + + beforeEach(async function () { + await openFileInEditor(driver, RESOURCES_REFERENCES, REFERENCES_FILE_1); + }); + + afterEach(async function () { + await clearReferences(); + await new EditorView().closeAllEditors(); + }); + + after(async function () { + await (await new ActivityBar().getViewControl('Explorer')).openView(); + }); + + it('direct reference not available while file with components not opened', async function () { + await noReferenceAvailable(5, 32); + }); + + it('direct reference available while file with components opened', async function () { + await referenceAvailable(5, 32, 'myDirectIDFromAnotherFile"/>'); + }); + + it('direct-vm reference not available while file with components not opened', async function () { + await noReferenceAvailable(10, 32); + }); + + it('direct-vm reference available while file with components opened', async function () { + await referenceAvailable(10, 32, 'myDirectVMIDFromAnotherFile"/>'); + }); + }); + }); + + describe('Java DSL support', function () { + this.timeout(DSL_TIMEOUT); + + describe('Camel URI code completion', function () { + + before(_setup(CAMEL_CONTEXT_JAVA)); + after(_clean(CAMEL_CONTEXT_JAVA)); + + beforeEach(async function () { + editor = await activateEditor(driver, CAMEL_CONTEXT_JAVA); + }); + + it('Open "camel-context.java" file inside Editor View', async function () { + await openContextInsideEditorView(CAMEL_CONTEXT_JAVA); + }); + + it('Code completion is working for component schemes (the part before the ":")', async function () { + await codeCompletionForComponentScheme(JAVA_URI_LINE, JAVA_URI_POSITION, 'from("timer:timerName").routeId("_fromID");'); + }); + + it('Code completion is working for endpoint options (the part after the "?")', async function () { + await codeCompletionForEndpointOptions(JAVA_URI_LINE, JAVA_URI_POSITION, 'from("timer:timerName?delay=1000").routeId("_fromID");'); + }); + + it('Code completion is working for additional endpoint options (the part after "&")', async function () { + await codeCompletionForAdditionalEndpointOptions(JAVA_URI_LINE, JAVA_URI_POSITION, false, 'from("timer:timerName?delay=1000&exchangePattern=").routeId("_fromID");'); + await codeCompletionForAdditionalEndpointOptionsValue(JAVA_URI_LINE, JAVA_URI_POSITION, false, 'from("timer:timerName?delay=1000&exchangePattern=InOnly").routeId("_fromID");'); + }); + }); + + describe('Endpoint options filtering', function () { + + before(_setup(CAMEL_CONTEXT_JAVA)); + after(_clean(CAMEL_CONTEXT_JAVA)); + + beforeEach(async function () { + await activateEditor(driver, CAMEL_CONTEXT_JAVA); + }); + + it('Duplicate endpoint options are filtered out', async function () { + await duplicateEndpointOptionsFiltering(JAVA_URI_LINE, JAVA_URI_POSITION, false); + }); + }); + + describe('Diagnostics for Camel URIs', function () { + + before(_setup(CAMEL_CONTEXT_JAVA)); + after(_clean(CAMEL_CONTEXT_JAVA)); + + beforeEach(async function () { + await activateEditor(driver, CAMEL_CONTEXT_JAVA); + }); + + it('LSP diagnostics support for Java DSL', async function () { + await lspDiagnosticSupport(JAVA_URI_LINE, JAVA_URI_POSITION); + }); + }); + }); + + describe('YAML DSL support', function () { + this.timeout(DSL_TIMEOUT); + + describe('Camel URI code completion', function () { + + before(_setup(CAMEL_CONTEXT_YAML)); + after(_clean(CAMEL_CONTEXT_YAML)); + + beforeEach(async function () { + await activateEditor(driver, CAMEL_CONTEXT_YAML); + }); + + it('Open "camel-context.yaml" file inside Editor View', async function () { + await openContextInsideEditorView(CAMEL_CONTEXT_YAML); + }); + + it('Code completion is working for component schemes (the part before the ":")', async function () { + await codeCompletionForComponentScheme(YAML_URI_LINE, YAML_URI_POSITION, 'uri: timer:timerName'); + }); + + it('Code completion is working for endpoint options (the part after the "?")', async function () { + await codeCompletionForEndpointOptions(YAML_URI_LINE, YAML_URI_POSITION, 'uri: timer:timerName?delay=1000'); + }); + + it('Code completion is working for additional endpoint options (the part after "&")', async function () { + await codeCompletionForAdditionalEndpointOptions(YAML_URI_LINE, YAML_URI_POSITION, false, 'uri: timer:timerName?delay=1000&exchangePattern='); + await codeCompletionForAdditionalEndpointOptionsValue(YAML_URI_LINE, YAML_URI_POSITION, false, 'uri: timer:timerName?delay=1000&exchangePattern=InOnly'); + }); + }); + + describe('Endpoint options filtering', function () { + + before(_setup(CAMEL_CONTEXT_YAML)); + after(_clean(CAMEL_CONTEXT_YAML)); + + beforeEach(async function () { + await activateEditor(driver, CAMEL_CONTEXT_YAML); + }); + + it('Duplicate endpoint options are filtered out', async function () { + await duplicateEndpointOptionsFiltering(YAML_URI_LINE, YAML_URI_POSITION, false); + }); + }); + }); + + describe('Groovy DSL support', function () { + this.timeout(DSL_TIMEOUT); + + before(_setup(GROOVY_TESTFILE)); + after(_clean(GROOVY_TESTFILE)); + + beforeEach(async function () { + await activateEditor(driver, GROOVY_TESTFILE); + }); + + it('Open "test.camelk.groovy" file inside Editor View', async function () { + await openContextInsideEditorView(GROOVY_TESTFILE); + }); + + it('Code completion is working for component schemes (the part before the ":")', async function () { + await codeCompletionForComponentScheme(GROOVY_URI_LINE, GROOVY_URI_POSITION, 'from(\'timer:timerName\')'); + }); + + it('Code completion is working for endpoint options (the part after the "?")', async function () { + await codeCompletionForEndpointOptions(GROOVY_URI_LINE, GROOVY_URI_POSITION, 'from(\'timer:timerName?delay=1000\')'); + }); + + it('Code completion is working for additional endpoint options (the part after "&")', async function () { + await codeCompletionForAdditionalEndpointOptions(GROOVY_URI_LINE, GROOVY_URI_POSITION, false, 'from(\'timer:timerName?delay=1000&exchangePattern=\')'); + await codeCompletionForAdditionalEndpointOptionsValue(GROOVY_URI_LINE, GROOVY_URI_POSITION, false, 'from(\'timer:timerName?delay=1000&exchangePattern=InOnly\')'); + }); + }); + + describe('Kotlin DSL support', function () { + this.timeout(DSL_TIMEOUT); + + before(_setup(KOTLIN_TESTFILE)); + after(_clean(KOTLIN_TESTFILE)); + + beforeEach(async function () { + await activateEditor(driver, KOTLIN_TESTFILE); + }); + + it('Open "test.camelk.kts" file inside Editor View', async function () { + await openContextInsideEditorView(KOTLIN_TESTFILE); + }); + + it('Code completion is working for component schemes (the part before the ":")', async function () { + await codeCompletionForComponentScheme(KOTLIN_URI_LINE, KOTLIN_URI_POSITION, 'from("timer:timerName")'); + }); + + it('Code completion is working for endpoint options (the part after the "?")', async function () { + await codeCompletionForEndpointOptions(KOTLIN_URI_LINE, KOTLIN_URI_POSITION, 'from("timer:timerName?delay=1000")'); + }); + + it('Code completion is working for additional endpoint options (the part after "&")', async function () { + await codeCompletionForAdditionalEndpointOptions(KOTLIN_URI_LINE, KOTLIN_URI_POSITION, false, 'from("timer:timerName?delay=1000&exchangePattern=")'); + await codeCompletionForAdditionalEndpointOptionsValue(KOTLIN_URI_LINE, KOTLIN_URI_POSITION, false, 'from("timer:timerName?delay=1000&exchangePattern=InOnly")'); + }); + }); + + describe('JavaScript DSL support', function () { + this.timeout(DSL_TIMEOUT); + + before(_setup(JS_TESTFILE)); + after(_clean(JS_TESTFILE)); + + beforeEach(async function () { + await activateEditor(driver, JS_TESTFILE); + }); + + it('Open "camel.js" file inside Editor View', async function () { + await openContextInsideEditorView(JS_TESTFILE); + }); + + it('Code completion is working for component schemes (the part before the ":")', async function () { + await codeCompletionForComponentScheme(JS_URI_LINE, JS_URI_POSITION, 'from(\'timer:timerName\')'); + }); + + it('Code completion is working for endpoint options (the part after the "?")', async function () { + await codeCompletionForEndpointOptions(JS_URI_LINE, JS_URI_POSITION, 'from(\'timer:timerName?delay=1000\')'); + }); + + it('Code completion is working for additional endpoint options (the part after "&")', async function () { + await codeCompletionForAdditionalEndpointOptions(JS_URI_LINE, JS_URI_POSITION, false, 'from(\'timer:timerName?delay=1000&exchangePattern=\')'); + await codeCompletionForAdditionalEndpointOptionsValue(JS_URI_LINE, JS_URI_POSITION, false, 'from(\'timer:timerName?delay=1000&exchangePattern=InOnly\')'); + }); + }); + // Camel URI code completion + /** + * Check, if required camel-context is opened inside editor. File is opened by before function. + * + * @param filename Filename of camel-context.* inside resources folder. + */ + async function openContextInsideEditorView(filename: string): Promise { + const editorName = await editor.getTitle(); + assert.equal(editorName, filename); + } + + /** + * Code completion is working for component schemes (the part before the ":"). + * + * @param uriLine Line number containing uri. + * @param uriPosition Position of uri on line. + * @param completedLine Expected form of completed line. + */ + async function codeCompletionForComponentScheme(uriLine: number, uriPosition: number, completedLine: string): Promise { + await editor.typeTextAt(uriLine, uriPosition, 'timer'); + const expectedContentAssist = 'timer:timerName' + contentAssist = await ca.waitUntilContentAssistContains(expectedContentAssist); + + const timer = await contentAssist.getItem(expectedContentAssist); + assert.equal(await getTextExt(timer), expectedContentAssist); + await timer.click(); + + assert.equal((await editor.getTextAtLine(uriLine)).trim(), completedLine); + } + + /** + * Code completion is working for endpoint options (the part after the "?"). + * + * @param uriLine Line number containing uri. + * @param uriPosition Position of uri on line. + * @param completedLine Expected form of completed line. + */ + async function codeCompletionForEndpointOptions(uriLine: number, uriPosition: number, completedLine: string): Promise { + await editor.typeTextAt(uriLine, uriPosition + 15, '?'); + contentAssist = await ca.waitUntilContentAssistContains('delay'); + const delay = await contentAssist.getItem('delay'); + assert.equal(await getTextExt(delay), 'delay'); + await delay.click(); + + assert.equal((await editor.getTextAtLine(uriLine)).trim(), completedLine); + } + + /** + * Code completion is working for additional endpoint options (the part after "&"). + * + * @param uriLine Line number containing uri. + * @param uriPosition Position of uri on line. + * @param anAmpersand Should be used '&' instead of '&'. + * @param completedLine Expected form of completed line. + */ + async function codeCompletionForAdditionalEndpointOptions(uriLine: number, uriPosition: number, anAmpersand: boolean, completedLine: string): Promise { + if (anAmpersand) { + await editor.typeTextAt(uriLine, uriPosition + 26, '&exchange'); + } else { + await editor.typeTextAt(uriLine, uriPosition + 26, '&'); + } + contentAssist = await ca.waitUntilContentAssistContains('exchangePattern'); + const exchange = await contentAssist.getItem('exchangePattern'); + assert.equal(await getTextExt(exchange), 'exchangePattern'); + await exchange.click(); + + assert.equal((await editor.getTextAtLine(uriLine)).trim(), completedLine); + } + + /** + * Code completion is working for additional endpoint options (the part after "&") with value. + * + * @param uriLine Line number containing uri. + * @param uriPosition Position of uri on line. + * @param anAmpersand Should be used '&' instead of '&'. + * @param completedLine Expected form of completed line. + */ + async function codeCompletionForAdditionalEndpointOptionsValue(uriLine: number, uriPosition: number, anAmpersand: boolean, completedLine: string): Promise { + if (anAmpersand) { + await editor.typeTextAt(uriLine, uriPosition + 47, 'In'); + } else { + await editor.typeTextAt(uriLine, uriPosition + 43, 'In'); + } + + contentAssist = await ca.waitUntilContentAssistContains('InOnly'); + const inOnly = await contentAssist.getItem('InOnly'); + assert.equal(await getTextExt(inOnly), 'InOnly'); + await inOnly.click(); + + assert.equal((await editor.getTextAtLine(uriLine)).trim(), completedLine); + } + + // Endpoint options filtering + /** + * Duplicate endpoint options are filtered out. + * + * @param uriLine Line number containing uri. + * @param uriPosition Position of uri on line. + * @param anAmpersand Should be used '&' instead of '&'. + */ + async function duplicateEndpointOptionsFiltering(uriLine: number, uriPosition: number, anAmpersand: boolean): Promise { + await editor.typeTextAt(uriLine, uriPosition, 'timer'); + contentAssist = await ca.waitUntilContentAssistContains('timer:timerName'); + const timer = await contentAssist.getItem('timer:timerName'); + await timer.click(); + + await editor.typeTextAt(uriLine, uriPosition + 15, '?'); + contentAssist = await ca.waitUntilContentAssistContains('delay'); + const delay = await contentAssist.getItem('delay'); + await delay.click(); + + if (anAmpersand) { + await editor.typeTextAt(uriLine, uriPosition + 26, '&de'); + } else { + await editor.typeTextAt(uriLine, uriPosition + 26, '&de'); + } + + contentAssist = await editor.toggleContentAssist(true) as ContentAssist; + await new WaitUntil().assistHasItems(contentAssist, DefaultWait.TimePeriod.DEFAULT); + const filtered = await contentAssist.hasItem('delay'); + + assert.isFalse(filtered); + await editor.toggleContentAssist(false); + } + + // Diagnostics for Camel URIs - XML ONLY + /** + * LSP diagnostics support for XML DSL. + * + * @param uriLine Line number containing uri. + * @param uriPosition Position of uri on line. + */ + async function lspDiagnosticSupport(uriLine: number, uriPosition: number): Promise { + const EXPECTED_ERROR_MESSAGE = 'Invalid duration value: 1000r'; + + await editor.typeTextAt(uriLine, uriPosition, 'timer'); + contentAssist = await ca.waitUntilContentAssistContains('timer:timerName'); + const timer = await contentAssist.getItem('timer:timerName'); + await timer.click(); + + await editor.typeTextAt(uriLine, uriPosition + 15, '?'); + contentAssist = await ca.waitUntilContentAssistContains('delay'); + const delay = await contentAssist.getItem('delay'); + await delay.click(); + + await editor.typeTextAt(uriLine, uriPosition + 26, 'r'); + const problemsView = await openProblemsView(); + + await driver.wait(async function () { + const innerMarkers = await problemsView.getAllVisibleMarkers(MarkerType.Error); + return innerMarkers.length > 0; + }, DefaultWait.TimePeriod.MEDIUM); + const markers = await problemsView.getAllVisibleMarkers(MarkerType.Error); + assert.isNotEmpty(markers, 'Problems view does not contains expected error'); + + const errorMessage = await markers[0].getText(); + assert.include(errorMessage, EXPECTED_ERROR_MESSAGE); + await new BottomBarPanel().toggle(false); // close Problems View + } + + // Auto-completion for referenced components IDs - XML ONLY + /** + * Auto-completion for referenced ID of "direct" component. + * + * @param uriLine Line number containing uri. + * @param uriPosition Position of uri on line. + * @param completedLine Expected form of completed line. + */ + async function autocompletionForReferenceIDofDirectComponent(uriLine: number, uriPosition: number, completedLine: string): Promise { + const DIRECT_COMPONENT_NAME = 'direct:testName'; + + await editor.typeTextAt(uriLine, uriPosition, DIRECT_COMPONENT_NAME); + contentAssist = await ca.waitUntilContentAssistContains(DIRECT_COMPONENT_NAME); + + const direct = await contentAssist.getItem(DIRECT_COMPONENT_NAME); + await direct.click(); + + assert.equal((await editor.getTextAtLine(uriLine)).trim(), completedLine); + } + + /** + * Auto-completion for referenced ID of "direct-vm" component. + * + * @param uriLine Line number containing uri. + * @param uriPosition Position of uri on line. + * @param completedLine Expected form of completed line. + */ + async function autocompletionForReferenceIDofDirectVMComponent(uriLine: number, uriPosition: number, completedLine: string): Promise { + const DIRECT_VM_COMPONENT_NAME = 'direct-vm:testName2'; + + await editor.typeTextAt(uriLine, uriPosition, DIRECT_VM_COMPONENT_NAME); + contentAssist = await ca.waitUntilContentAssistContains(DIRECT_VM_COMPONENT_NAME); + + const directVM = await contentAssist.getItem(DIRECT_VM_COMPONENT_NAME); + await directVM.click(); + + assert.equal((await editor.getTextAtLine(uriLine)).trim(), completedLine); + } + + /** + * Checks if no item in 'Reference' SideBar is available for selected component in 'camel1.xml'. + * + * @param uriLine Line number containing uri. + * @param uriPosition Position of uri on line. + */ + async function noReferenceAvailable(uriLine: number, uriPosition: number): Promise { + editor = await activateEditor(driver, REFERENCES_FILE_1); + await editor.moveCursor(uriLine, uriPosition); // get to position in code + await new Workbench().executeCommand('references-view.findReferences'); + assert.isFalse(await isReferencesAvailable()); // no reference should be available + } + + /** + * Checks if expected item is available in 'Reference' SideBar. + * Used files are 'camel1.xml' as main opened file and 'camel2.xml' as file with reference. + * + * @param uriLine Line number containing uri. + * @param uriPosition Position of uri on line. + * @param expectedReference Expected reference. + */ + async function referenceAvailable(uriLine: number, uriPosition: number, expectedReference: string): Promise { + await openFileInEditor(driver, RESOURCES_REFERENCES, REFERENCES_FILE_2); // has to be opened + + editor = await activateEditor(driver, REFERENCES_FILE_1); // switch to other file + assert.isTrue((await editor.getTitle()).startsWith(REFERENCES_FILE_1)); + await editor.moveCursor(uriLine, uriPosition); // get to position in code + + await new Workbench().executeCommand('references-view.findReferences'); // find all references + + // wait until 'References' refreshed + await driver.wait(async function () { + return (await isReferencesAvailable()); + }, 15000); + + const section = await new SideBarView().getContent().getSection('References') as DefaultTreeSection; + const visibleItems = await section.getVisibleItems(); + assert.equal(await visibleItems.at(0).getLabel(), REFERENCES_FILE_2); + assert.equal(await visibleItems.at(1).getLabel(), expectedReference); + } +}); diff --git a/src/ui-test/tests/xx_check.camel.version.test.ts b/src/ui-test/tests/xx_check.camel.version.test.ts new file mode 100644 index 000000000..68546132a --- /dev/null +++ b/src/ui-test/tests/xx_check.camel.version.test.ts @@ -0,0 +1,31 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License", destination); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { assert } from "chai"; +import { CATALOG_VERSION_ID, readUserSetting } from "../utils/testUtils"; + +describe('check camel version at end', function () { + this.timeout(15000); + + it('actual version at end ', async function () { + + if(process.env.CAMEL_VERSION == null || process.env.CAMEL_VERSION.length == 0){ + this.skip(); + } + + assert.equal(readUserSetting(CATALOG_VERSION_ID), process.env.CAMEL_VERSION) + }); +}); diff --git a/src/ui-test/utils/testUtils.ts b/src/ui-test/utils/testUtils.ts index ebbbab55a..a2d33b060 100644 --- a/src/ui-test/utils/testUtils.ts +++ b/src/ui-test/utils/testUtils.ts @@ -182,6 +182,31 @@ export function resetUserSettings(id: string): void { fs.writeFileSync(settingsPath, reset, 'utf-8'); } +/** + * TODO: tohle zpusobuje pady kdyz je to null + * + * @param id TODO. + */ +export function readUserSetting(id: string): string | null { + + const settingsPath = path.resolve(storageFolder, 'settings', 'User', 'settings.json'); + const settingsContent = fs.readFileSync(settingsPath, 'utf-8'); + +// console.log("text\n\n" + settingsContent + "\n\n"); + + const regex = new RegExp(`"${id}":\\s*"(.*?)"`, 'i'); + const match = settingsContent.match(regex); + +// console.log("regex: " + regex); +// console.log("match: " + match); + + if (match == null){ + return null; + } else { + return match[1]; + } +} + /** * Delete file from folder. *