diff --git a/clients/client-acm/package.json b/clients/client-acm/package.json index c9199d92ab1c..b65d7a35fc69 100644 --- a/clients/client-acm/package.json +++ b/clients/client-acm/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo acm", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-acm/test/acm-features.e2e.spec.ts b/clients/client-acm/test/acm-features.e2e.spec.ts new file mode 100644 index 000000000000..e066b1ca90d7 --- /dev/null +++ b/clients/client-acm/test/acm-features.e2e.spec.ts @@ -0,0 +1,39 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { ACM } from "@aws-sdk/client-acm"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("@aws-sdk/client-acm", () => { + let client: ACM; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new ACM({ region }); + }); + + describe("Making a request to ACM service", () => { + it("should successfully list certificates", async () => { + const result = await client.listCertificates({}); + + expect(Array.isArray(result.CertificateSummaryList)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should handle ValidationException for invalid certificate ARN", async () => { + await expect( + client.describeCertificate({ + CertificateArn: "fake_arn", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationException", + }) + ); + }); + }); +}); diff --git a/clients/client-acm/vitest.config.e2e.mts b/clients/client-acm/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-acm/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-api-gateway/package.json b/clients/client-api-gateway/package.json index 9823946cc2a6..1dded43fbe2b 100644 --- a/clients/client-api-gateway/package.json +++ b/clients/client-api-gateway/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo api-gateway", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-api-gateway/test/apigateway-features.e2e.spec.ts b/clients/client-api-gateway/test/apigateway-features.e2e.spec.ts new file mode 100644 index 000000000000..1f63811a3091 --- /dev/null +++ b/clients/client-api-gateway/test/apigateway-features.e2e.spec.ts @@ -0,0 +1,39 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { APIGateway } from "@aws-sdk/client-api-gateway"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("@aws-sdk/client-api-gateway", () => { + let client: APIGateway; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new APIGateway({ region }); + }); + + describe("Making a request", () => { + it("should successfully get REST APIs", async () => { + const result = await client.getRestApis({}); + + expect(Array.isArray(result.items)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should handle NotFoundException for invalid REST API ID", async () => { + await expect( + client.getRestApi({ + restApiId: "fake_id", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "NotFoundException", + }) + ); + }); + }); +}); diff --git a/clients/client-api-gateway/vitest.config.e2e.mts b/clients/client-api-gateway/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-api-gateway/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-cloudformation/package.json b/clients/client-cloudformation/package.json index f641ad396092..7a22419178f5 100644 --- a/clients/client-cloudformation/package.json +++ b/clients/client-cloudformation/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo cloudformation", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-cloudformation/test/cloudformation-features.e2e.spec.ts b/clients/client-cloudformation/test/cloudformation-features.e2e.spec.ts new file mode 100644 index 000000000000..7b223cab841a --- /dev/null +++ b/clients/client-cloudformation/test/cloudformation-features.e2e.spec.ts @@ -0,0 +1,62 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { CloudFormation, paginateListStacks } from "@aws-sdk/client-cloudformation"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("@aws-sdk/client-cloudformation", () => { + let client: CloudFormation; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new CloudFormation({ region }); + }); + + describe("Describing stacks", () => { + it("should return stacks list when describe stacks is called", async () => { + const result = await client.describeStacks({}); + + expect(result).toBeDefined(); + expect(result.Stacks).toBeDefined(); + expect(Array.isArray(result.Stacks)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should handle ValidationError for invalid stack creation", async () => { + const templateBody = '{"Resources":{"member":{"Type":"AWS::SQS::Queue"}}}'; + + await expect( + client.createStack({ + TemplateBody: templateBody, + StackName: "", // Empty name should cause ValidationError + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationError", + }) + ); + }); + }); + + describe("Paginating responses", () => { + it("should paginate listStacks operation", async () => { + const paginator = paginateListStacks({ client }, {}); + + let pageCount = 0; + let lastPage; + + for await (const page of paginator) { + pageCount++; + lastPage = page; + } + + expect(pageCount).toBeGreaterThanOrEqual(1); + expect(lastPage).toBeDefined(); + expect(lastPage?.NextToken).toBeUndefined(); // The last page must not contain a marker + }); + }); +}); diff --git a/clients/client-cloudformation/vitest.config.e2e.mts b/clients/client-cloudformation/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-cloudformation/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-cloudfront/package.json b/clients/client-cloudfront/package.json index ad519725da83..1277b2643176 100644 --- a/clients/client-cloudfront/package.json +++ b/clients/client-cloudfront/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo cloudfront", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-cloudfront/test/cloudfront-features.e2e.spec.ts b/clients/client-cloudfront/test/cloudfront-features.e2e.spec.ts new file mode 100644 index 000000000000..1f070a6500fa --- /dev/null +++ b/clients/client-cloudfront/test/cloudfront-features.e2e.spec.ts @@ -0,0 +1,159 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { CloudFront } from "@aws-sdk/client-cloudfront"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("@aws-sdk/client-cloudfront", () => { + let client: CloudFront; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new CloudFront({ region }); + }, 60_000); + + describe("List distributions", () => { + it("should return distribution list with quantity property", async () => { + const result = await client.listDistributions({}); + + expect(typeof result.DistributionList?.Quantity).toBe("number"); + }); + }); + + describe("Create a distribution", () => { + it("should handle NoSuchOrigin error for invalid origin", async () => { + const uniqueRef = `aws-js-sdk-${Date.now()}-${process.pid}-${Math.random().toString(36).substr(2, 9)}`; + const distributionConfig = { + CallerReference: uniqueRef, + Aliases: { + Quantity: 0, + }, + DefaultRootObject: "", + Origins: { + Items: [ + { + Id: "InvalidOrigin", + DomainName: "example.com", + CustomOriginConfig: { + HTTPPort: 80, + HTTPSPort: 443, + OriginProtocolPolicy: "match-viewer" as const, + }, + }, + ], + Quantity: 1, + }, + DefaultCacheBehavior: { + TargetOriginId: "NonExistentOrigin", + ForwardedValues: { + QueryString: false, + Cookies: { + Forward: "all" as const, + }, + }, + TrustedSigners: { + Items: [], + Enabled: false, + Quantity: 0, + }, + ViewerProtocolPolicy: "allow-all" as const, + MinTTL: 0, + }, + CacheBehaviors: { + Items: [], + Quantity: 0, + }, + Comment: "", + Logging: { + Enabled: false, + Bucket: "invalidbucket.s3.amazonaws.com", + Prefix: "prefix", + IncludeCookies: false, + }, + PriceClass: "PriceClass_All" as const, + Enabled: false, + }; + + await expect( + client.createDistribution({ + DistributionConfig: distributionConfig, + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "NoSuchOrigin", + $metadata: expect.objectContaining({ + httpStatusCode: 404, + }), + }) + ); + }); + }); + + describe("Error handling", () => { + it("should handle InvalidArgument for empty name prefix", async () => { + const distributionConfig = { + CallerReference: "", + Aliases: { + Quantity: 0, + }, + DefaultRootObject: "", + Origins: { + Items: [ + { + Id: "origin", + DomainName: "example.com", + CustomOriginConfig: { + HTTPPort: 80, + HTTPSPort: 443, + OriginProtocolPolicy: "match-viewer" as const, + }, + }, + ], + Quantity: 1, + }, + DefaultCacheBehavior: { + TargetOriginId: "origin", + ForwardedValues: { + QueryString: false, + Cookies: { + Forward: "all" as const, + }, + }, + TrustedSigners: { + Items: [], + Enabled: false, + Quantity: 0, + }, + ViewerProtocolPolicy: "allow-all" as const, + MinTTL: 0, + }, + CacheBehaviors: { + Items: [], + Quantity: 0, + }, + Comment: "", + Logging: { + Enabled: false, + Bucket: "invalidbucket.s3.amazonaws.com", + Prefix: "prefix", + IncludeCookies: false, + }, + PriceClass: "PriceClass_All" as const, + Enabled: false, + }; + + await expect( + client.createDistribution({ + DistributionConfig: distributionConfig, + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "InvalidArgument", + }) + ); + }); + }); +}, 60_000); diff --git a/clients/client-cloudfront/vitest.config.e2e.mts b/clients/client-cloudfront/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-cloudfront/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-cloudtrail/package.json b/clients/client-cloudtrail/package.json index f71c3e583d0c..4fe20afa87ca 100644 --- a/clients/client-cloudtrail/package.json +++ b/clients/client-cloudtrail/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo cloudtrail", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-cloudtrail/test/cloudtrail-features.e2e.spec.ts b/clients/client-cloudtrail/test/cloudtrail-features.e2e.spec.ts new file mode 100644 index 000000000000..9ca5c7706dc6 --- /dev/null +++ b/clients/client-cloudtrail/test/cloudtrail-features.e2e.spec.ts @@ -0,0 +1,41 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { CloudTrail } from "@aws-sdk/client-cloudtrail"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("@aws-sdk/client-cloudtrail", () => { + let client: CloudTrail; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new CloudTrail({ region }); + }); + + describe("Describe trails", () => { + it("should return trails list when describe trails is called", async () => { + const result = await client.describeTrails({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + }); + }); + + describe("Error handling", () => { + it("should handle InvalidTrailNameException for invalid trail name", async () => { + await expect( + client.createTrail({ + Name: "", // Empty name should cause InvalidTrailNameException + S3BucketName: "test-bucket", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "InvalidTrailNameException", + message: expect.stringContaining("cannot be blank"), + }) + ); + }); + }); +}); diff --git a/clients/client-cloudtrail/vitest.config.e2e.mts b/clients/client-cloudtrail/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-cloudtrail/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-cloudwatch-events/package.json b/clients/client-cloudwatch-events/package.json index a2285d45d4ec..c429946dda37 100644 --- a/clients/client-cloudwatch-events/package.json +++ b/clients/client-cloudwatch-events/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo cloudwatch-events", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-cloudwatch-events/test/cloudwatch-events-features.e2e.spec.ts b/clients/client-cloudwatch-events/test/cloudwatch-events-features.e2e.spec.ts new file mode 100644 index 000000000000..e458da31e6e8 --- /dev/null +++ b/clients/client-cloudwatch-events/test/cloudwatch-events-features.e2e.spec.ts @@ -0,0 +1,36 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { CloudWatchEvents } from "@aws-sdk/client-cloudwatch-events"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("@aws-sdk/client-cloudwatch-events", () => { + let client: CloudWatchEvents; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new CloudWatchEvents({ region }); + }); + + describe("Making a request", () => { + it("should successfully list rules and return Rules as a list", async () => { + const result = await client.listRules({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.Rules)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should handle ResourceNotFoundException for fake rule", async () => { + await expect(client.describeRule({ Name: "fake_rule" })).rejects.toThrow( + expect.objectContaining({ + name: "ResourceNotFoundException", + }) + ); + }); + }); +}); diff --git a/clients/client-cloudwatch-events/vitest.config.e2e.mts b/clients/client-cloudwatch-events/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-cloudwatch-events/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-cloudwatch-logs/test/cloudwatch-logs-features.e2e.spec.ts b/clients/client-cloudwatch-logs/test/cloudwatch-logs-features.e2e.spec.ts new file mode 100644 index 000000000000..da4e30b7c69b --- /dev/null +++ b/clients/client-cloudwatch-logs/test/cloudwatch-logs-features.e2e.spec.ts @@ -0,0 +1,60 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { CloudWatchLogs, InvalidParameterException } from "@aws-sdk/client-cloudwatch-logs"; +import { afterAll, beforeAll, describe, expect, test as it } from "vitest"; + +describe("CloudWatch Logs Features", () => { + let client: CloudWatchLogs; + let region: string; + const createdLogGroups: string[] = []; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new CloudWatchLogs({ region }); + }); + + const generateLogGroupName = (prefix: string) => { + const timestamp = Date.now(); + const random = Math.random().toString(36).substring(7); + return prefix ? `${prefix}-${timestamp}-${random}` : ""; + }; + + afterAll(async () => { + // Cleanup created log groups + for (const logGroupName of createdLogGroups) { + try { + await client.deleteLogGroup({ logGroupName }); + } catch (error) { + console.warn(`Failed to cleanup log group ${logGroupName}:`, error); + } + } + }); + + describe("Log Groups", () => { + it("should create a log group and list it", async () => { + // Given I create a CloudWatch logGroup with prefix "aws-js-sdk" + const logGroupName = generateLogGroupName("aws-js-sdk"); + createdLogGroups.push(logGroupName); + + await client.createLogGroup({ logGroupName }); + + // And I list the CloudWatch logGroups + const response = await client.describeLogGroups({ + logGroupNamePrefix: logGroupName, + }); + + // Then the list should contain the CloudWatch logGroup + expect(response.logGroups?.some((group) => group.logGroupName === logGroupName)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should throw InvalidParameterException for empty prefix", async () => { + const logGroupName = generateLogGroupName(""); + await expect(client.createLogGroup({ logGroupName })).rejects.toThrow(InvalidParameterException); + }); + }); +}); diff --git a/clients/client-cloudwatch/test/e2e/cloudwatch-features.e2e.spec.ts b/clients/client-cloudwatch/test/e2e/cloudwatch-features.e2e.spec.ts new file mode 100644 index 000000000000..bc6cf654b693 --- /dev/null +++ b/clients/client-cloudwatch/test/e2e/cloudwatch-features.e2e.spec.ts @@ -0,0 +1,69 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { CloudWatch } from "@aws-sdk/client-cloudwatch"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("@aws-sdk/client-cloudwatch", () => { + let client: CloudWatch; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new CloudWatch({ region }); + }); + + describe("Alarms", () => { + it("should create, list, and find CloudWatch alarm", async () => { + const alarmName = `aws-js-sdk-alarm-${Date.now()}`; + + // Create alarm + await client.putMetricAlarm({ + AlarmName: alarmName, + ComparisonOperator: "GreaterThanThreshold", + EvaluationPeriods: 1, + AlarmDescription: "Test alarm for SDK", + MetricName: "CPUUtilization", + Namespace: "AWS/EC2", + Statistic: "Average", + Threshold: 80, + Period: 300, + }); + + // List alarms + const result = await client.describeAlarms({}); + + expect(Array.isArray(result.MetricAlarms)).toBe(true); + + // Check if our alarm is in the list + const foundAlarm = result.MetricAlarms?.find((alarm) => alarm.AlarmName === alarmName); + expect(foundAlarm?.AlarmName).toBe(alarmName); + + // Cleanup + await client.deleteAlarms({ AlarmNames: [alarmName] }); + }); + }); + + describe("Error handling", () => { + it("should handle ValidationError for empty alarm name", async () => { + await expect( + client.putMetricAlarm({ + AlarmName: "", // Empty name should cause ValidationError + ComparisonOperator: "GreaterThanThreshold", + EvaluationPeriods: 1, + MetricName: "CPUUtilization", + Namespace: "AWS/EC2", + Statistic: "Average", + Threshold: 80, + Period: 300, + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationError", + }) + ); + }); + }); +}); diff --git a/clients/client-codecommit/package.json b/clients/client-codecommit/package.json index 85416852ab47..d2c2b2ce84c5 100644 --- a/clients/client-codecommit/package.json +++ b/clients/client-codecommit/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo codecommit", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-codecommit/test/codecommit-features.e2e.spec.ts b/clients/client-codecommit/test/codecommit-features.e2e.spec.ts new file mode 100644 index 000000000000..b0aa28dbd9cf --- /dev/null +++ b/clients/client-codecommit/test/codecommit-features.e2e.spec.ts @@ -0,0 +1,32 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { CodeCommit, RepositoryDoesNotExistException } from "@aws-sdk/client-codecommit"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("AWS CodeCommit Features", () => { + let client: CodeCommit; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new CodeCommit({ region }); + }); + + describe("List repositories", () => { + it("should successfully list repositories", async () => { + const result = await client.listRepositories({}); + expect(Array.isArray(result.repositories)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should throw RepositoryDoesNotExistException for fake repository", async () => { + await expect(client.listBranches({ repositoryName: "fake-repo" })).rejects.toThrow( + RepositoryDoesNotExistException + ); + }); + }); +}); diff --git a/clients/client-codecommit/vitest.config.e2e.mts b/clients/client-codecommit/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-codecommit/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-codedeploy/package.json b/clients/client-codedeploy/package.json index 7499dd0160e1..ecd82120ce19 100644 --- a/clients/client-codedeploy/package.json +++ b/clients/client-codedeploy/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo codedeploy", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-codedeploy/test/codedeploy-features.e2e.spec.ts b/clients/client-codedeploy/test/codedeploy-features.e2e.spec.ts new file mode 100644 index 000000000000..a14331fd7891 --- /dev/null +++ b/clients/client-codedeploy/test/codedeploy-features.e2e.spec.ts @@ -0,0 +1,39 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { CodeDeploy } from "@aws-sdk/client-codedeploy"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("@aws-sdk/client-codedeploy", () => { + let client: CodeDeploy; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new CodeDeploy({ region }); + }); + + describe("Listing Applications", () => { + it("should return applications list when listApplications is called", async () => { + const result = await client.listApplications({}); + + expect(Array.isArray(result.applications)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should handle ApplicationNameRequiredException for empty application name", async () => { + await expect( + client.createApplication({ + applicationName: "", // Empty name should cause ApplicationNameRequiredException + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ApplicationNameRequiredException", + }) + ); + }); + }); +}); diff --git a/clients/client-codedeploy/vitest.config.e2e.mts b/clients/client-codedeploy/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-codedeploy/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-codepipeline/package.json b/clients/client-codepipeline/package.json index 5113ac09ae50..cc82730671ba 100644 --- a/clients/client-codepipeline/package.json +++ b/clients/client-codepipeline/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo codepipeline", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-codepipeline/test/codepipeline-features.e2e.spec.ts b/clients/client-codepipeline/test/codepipeline-features.e2e.spec.ts new file mode 100644 index 000000000000..8c0374844482 --- /dev/null +++ b/clients/client-codepipeline/test/codepipeline-features.e2e.spec.ts @@ -0,0 +1,39 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { CodePipeline } from "@aws-sdk/client-codepipeline"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("@aws-sdk/client-codepipeline", () => { + let client: CodePipeline; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new CodePipeline({ region }); + }); + + describe("Listing Pipelines", () => { + it("should return pipelines list when listPipelines is called", async () => { + const result = await client.listPipelines({}); + + expect(Array.isArray(result.pipelines)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should handle PipelineNotFoundException for fake pipeline", async () => { + await expect( + client.getPipeline({ + name: "fake-pipeline", // Non-existent pipeline should cause PipelineNotFoundException + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "PipelineNotFoundException", + }) + ); + }); + }); +}); diff --git a/clients/client-codepipeline/vitest.config.e2e.mts b/clients/client-codepipeline/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-codepipeline/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-cognito-identity/test/e2e/cognitoidentity-features.e2e.spec.ts b/clients/client-cognito-identity/test/e2e/cognitoidentity-features.e2e.spec.ts new file mode 100644 index 000000000000..cac165689e09 --- /dev/null +++ b/clients/client-cognito-identity/test/e2e/cognitoidentity-features.e2e.spec.ts @@ -0,0 +1,64 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { CognitoIdentity } from "@aws-sdk/client-cognito-identity"; +import { afterAll, beforeAll, describe, expect, test as it } from "vitest"; + +describe("@aws-sdk/client-cognito-identity", () => { + let client: CognitoIdentity; + let region: string; + let createdIdentityPoolId: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new CognitoIdentity({ region }); + }); + + afterAll(async () => { + if (createdIdentityPoolId) { + try { + await client.deleteIdentityPool({ IdentityPoolId: createdIdentityPoolId }); + } catch (error) { + console.warn("Failed to clean up identity pool:", error); + } + } + }); + + describe("Identity Pools", () => { + it("should create and describe a Cognito identity pool", async () => { + // Create identity pool + const createResult = await client.createIdentityPool({ + IdentityPoolName: `awssdkjs-test-${Date.now()}`, + AllowUnauthenticatedIdentities: true, + }); + + expect(createResult.IdentityPoolId).toBeDefined(); + createdIdentityPoolId = createResult.IdentityPoolId!; + + // Describe the identity pool + const describeResult = await client.describeIdentityPool({ + IdentityPoolId: createdIdentityPoolId, + }); + + expect(describeResult).toBeDefined(); + expect(describeResult.IdentityPoolId).toBe(createdIdentityPoolId); + }); + }); + + describe("Error handling", () => { + it("should handle ValidationException for empty identity pool name", async () => { + await expect( + client.createIdentityPool({ + IdentityPoolName: "", // Empty name should cause ValidationException + AllowUnauthenticatedIdentities: true, + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationException", + }) + ); + }); + }); +}); diff --git a/clients/client-cognito-sync/package.json b/clients/client-cognito-sync/package.json index 44d551c82523..15d96579120e 100644 --- a/clients/client-cognito-sync/package.json +++ b/clients/client-cognito-sync/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo cognito-sync", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-cognito-sync/test/cognitosync-features.e2e.spec.ts b/clients/client-cognito-sync/test/cognitosync-features.e2e.spec.ts new file mode 100644 index 000000000000..5ef943883ff2 --- /dev/null +++ b/clients/client-cognito-sync/test/cognitosync-features.e2e.spec.ts @@ -0,0 +1,41 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { CognitoSync } from "@aws-sdk/client-cognito-sync"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon Cognito Sync Features", () => { + let client: CognitoSync; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new CognitoSync({ region }); + }); + + describe("Identity Pool Usage", () => { + it("should successfully list identity pool usage", async () => { + const result = await client.listIdentityPoolUsage({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(result.IdentityPoolUsages).toBeDefined(); + }); + }); + + describe("Error handling", () => { + it("should contain validation error for invalid parameters", async () => { + await expect( + client.listDatasets({ + IdentityPoolId: "INVALID", + IdentityId: "A:B:C", + }) + ).rejects.toThrow( + expect.objectContaining({ + message: expect.stringContaining("validation errors detected"), + }) + ); + }); + }); +}); diff --git a/clients/client-cognito-sync/vitest.config.e2e.mts b/clients/client-cognito-sync/vitest.config.e2e.mts new file mode 100644 index 000000000000..a08a0dfa31c3 --- /dev/null +++ b/clients/client-cognito-sync/vitest.config.e2e.mts @@ -0,0 +1,8 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + include: ["**/*.e2e.spec.ts"], + environment: "happy-dom", + }, +}); diff --git a/clients/client-config-service/package.json b/clients/client-config-service/package.json index 0846e61e2fb9..ce99313a7f68 100644 --- a/clients/client-config-service/package.json +++ b/clients/client-config-service/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo config-service", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-config-service/test/configservice-features.e2e.spec.ts b/clients/client-config-service/test/configservice-features.e2e.spec.ts new file mode 100644 index 000000000000..db7c34da2710 --- /dev/null +++ b/clients/client-config-service/test/configservice-features.e2e.spec.ts @@ -0,0 +1,40 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { ConfigService } from "@aws-sdk/client-config-service"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("AWS Config Features", () => { + let client: ConfigService; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new ConfigService({ region }); + }); + + describe("Listing delivery channels", () => { + it("should successfully describe delivery channels", async () => { + const result = await client.describeDeliveryChannels({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.DeliveryChannels)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain validation error for invalid parameters", async () => { + await expect( + client.putDeliveryChannel({ + DeliveryChannel: { name: "" }, + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationException", + }) + ); + }); + }); +}); diff --git a/clients/client-config-service/vitest.config.e2e.mts b/clients/client-config-service/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-config-service/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-data-pipeline/package.json b/clients/client-data-pipeline/package.json index 1553296d44ec..98f1e8041324 100644 --- a/clients/client-data-pipeline/package.json +++ b/clients/client-data-pipeline/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo data-pipeline", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-data-pipeline/test/datapipeline-features.e2e.spec.ts b/clients/client-data-pipeline/test/datapipeline-features.e2e.spec.ts new file mode 100644 index 000000000000..6ff766ecd120 --- /dev/null +++ b/clients/client-data-pipeline/test/datapipeline-features.e2e.spec.ts @@ -0,0 +1,42 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { DataPipeline } from "@aws-sdk/client-data-pipeline"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("AWS Data Pipeline Features", () => { + let client: DataPipeline; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new DataPipeline({ region }); + }); + + describe("Listing pipelines", () => { + it("should successfully list pipelines", async () => { + const result = await client.listPipelines({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.pipelineIdList)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain validation error for empty name prefix", async () => { + await expect( + client.createPipeline({ + name: "", + uniqueId: "test-unique-id-" + Date.now(), + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationException", + message: expect.stringContaining("Member must have length greater than or equal to 1"), + }) + ); + }); + }); +}); diff --git a/clients/client-data-pipeline/vitest.config.e2e.mts b/clients/client-data-pipeline/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-data-pipeline/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-database-migration-service/package.json b/clients/client-database-migration-service/package.json index 16083c2a2412..e0bf4e8a1215 100644 --- a/clients/client-database-migration-service/package.json +++ b/clients/client-database-migration-service/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo database-migration-service", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-database-migration-service/test/dms-features.e2e.spec.ts b/clients/client-database-migration-service/test/dms-features.e2e.spec.ts new file mode 100644 index 000000000000..a8ed993b0e1b --- /dev/null +++ b/clients/client-database-migration-service/test/dms-features.e2e.spec.ts @@ -0,0 +1,41 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { DatabaseMigrationService } from "@aws-sdk/client-database-migration-service"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("AWS Database Migration Service Features", () => { + let client: DatabaseMigrationService; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new DatabaseMigrationService({ region }); + }); + + describe("Making a request", () => { + it("should successfully describe endpoints", async () => { + const result = await client.describeEndpoints({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.Endpoints)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain invalid parameter error for fake ARN", async () => { + await expect( + client.startReplicationTask({ + ReplicationTaskArn: "fake-arn", + StartReplicationTaskType: "start-replication", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "InvalidParameterValueException", + }) + ); + }); + }); +}); diff --git a/clients/client-database-migration-service/vitest.config.e2e.mts b/clients/client-database-migration-service/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-database-migration-service/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-device-farm/package.json b/clients/client-device-farm/package.json index 8b409e3ca029..6f0c05c702a3 100644 --- a/clients/client-device-farm/package.json +++ b/clients/client-device-farm/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo device-farm", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-device-farm/test/devicefarm-features.e2e.spec.ts b/clients/client-device-farm/test/devicefarm-features.e2e.spec.ts new file mode 100644 index 000000000000..8f3a16331063 --- /dev/null +++ b/clients/client-device-farm/test/devicefarm-features.e2e.spec.ts @@ -0,0 +1,40 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { DeviceFarm } from "@aws-sdk/client-device-farm"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("AWS Device Farm", () => { + let client: DeviceFarm; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new DeviceFarm({ region }); + }); + + describe("Listing devices", () => { + it("should successfully list devices", async () => { + const result = await client.listDevices({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.devices)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain not found error for invalid device ARN", async () => { + await expect( + client.getDevice({ + arn: "arn:aws:devicefarm:us-west-2::device:00000000000000000000000000000000", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "NotFoundException", + }) + ); + }); + }); +}); diff --git a/clients/client-device-farm/vitest.config.e2e.mts b/clients/client-device-farm/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-device-farm/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-direct-connect/package.json b/clients/client-direct-connect/package.json index 7c99dcba2ea9..6df5a235fba2 100644 --- a/clients/client-direct-connect/package.json +++ b/clients/client-direct-connect/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo direct-connect", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-direct-connect/test/directconnect-features.e2e.spec.ts b/clients/client-direct-connect/test/directconnect-features.e2e.spec.ts new file mode 100644 index 000000000000..297db2fd962f --- /dev/null +++ b/clients/client-direct-connect/test/directconnect-features.e2e.spec.ts @@ -0,0 +1,42 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { DirectConnect } from "@aws-sdk/client-direct-connect"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("AWS Direct Connect", () => { + let client: DirectConnect; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new DirectConnect({ region }); + }); + + describe("describe connections", () => { + it("should successfully describe connections", async () => { + const result = await client.describeConnections({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.connections)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain client exception for invalid location", async () => { + await expect( + client.createConnection({ + location: "invalid-location", + bandwidth: "1Gbps", + connectionName: "test-connection", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "DirectConnectClientException", + }) + ); + }); + }); +}); diff --git a/clients/client-direct-connect/vitest.config.e2e.mts b/clients/client-direct-connect/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-direct-connect/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-directory-service/package.json b/clients/client-directory-service/package.json index 09f2dac8a2af..14c6a3eb5e53 100644 --- a/clients/client-directory-service/package.json +++ b/clients/client-directory-service/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo directory-service", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-directory-service/test/directoryservice-features.e2e.spec.ts b/clients/client-directory-service/test/directoryservice-features.e2e.spec.ts new file mode 100644 index 000000000000..0cef7aeb5990 --- /dev/null +++ b/clients/client-directory-service/test/directoryservice-features.e2e.spec.ts @@ -0,0 +1,42 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { DirectoryService } from "@aws-sdk/client-directory-service"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("AWS Directory Service Features", () => { + let client: DirectoryService; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new DirectoryService({ region }); + }); + + describe("Listing directories", () => { + it("should successfully describe directories", async () => { + const result = await client.describeDirectories({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.DirectoryDescriptions)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain validation error for invalid parameters", async () => { + await expect( + client.createDirectory({ + Name: "", + Password: "", + Size: "" as any, + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationException", + }) + ); + }); + }); +}); diff --git a/clients/client-directory-service/vitest.config.e2e.mts b/clients/client-directory-service/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-directory-service/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-dynamodb-streams/package.json b/clients/client-dynamodb-streams/package.json index 79127dc11aa8..8e0ef2aced57 100644 --- a/clients/client-dynamodb-streams/package.json +++ b/clients/client-dynamodb-streams/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo dynamodb-streams", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-dynamodb-streams/test/dynamodbstreams-features.e2e.spec.ts b/clients/client-dynamodb-streams/test/dynamodbstreams-features.e2e.spec.ts new file mode 100644 index 000000000000..1aeb622fb8ed --- /dev/null +++ b/clients/client-dynamodb-streams/test/dynamodbstreams-features.e2e.spec.ts @@ -0,0 +1,40 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { DynamoDBStreams } from "@aws-sdk/client-dynamodb-streams"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon DynamoDB Streams Features", () => { + let client: DynamoDBStreams; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new DynamoDBStreams({ region }); + }); + + describe("Listing streams", () => { + it("should successfully list streams", async () => { + const result = await client.listStreams({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.Streams)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain validation error for invalid stream ARN", async () => { + await expect( + client.describeStream({ + StreamArn: "fake-stream", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationException", + }) + ); + }); + }); +}); diff --git a/clients/client-dynamodb-streams/vitest.config.e2e.mts b/clients/client-dynamodb-streams/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-dynamodb-streams/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-dynamodb/test/dynamodb-features.e2e.spec.ts b/clients/client-dynamodb/test/dynamodb-features.e2e.spec.ts new file mode 100644 index 000000000000..301cac28bd18 --- /dev/null +++ b/clients/client-dynamodb/test/dynamodb-features.e2e.spec.ts @@ -0,0 +1,139 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { DynamoDB, waitUntilTableExists } from "@aws-sdk/client-dynamodb"; +import { afterAll, beforeAll, describe, expect, test as it } from "vitest"; + +describe("DynamoDB Tables Features", () => { + let client: DynamoDB; + let region: string; + let sharedTableName: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new DynamoDB({ region }); + + // Create shared table for tests + sharedTableName = `aws-sdk-js-integration`; + await client.createTable({ + TableName: sharedTableName, + AttributeDefinitions: [{ AttributeName: "id", AttributeType: "S" }], + KeySchema: [{ AttributeName: "id", KeyType: "HASH" }], + BillingMode: "PAY_PER_REQUEST", + }); + + // Wait for table to be active + await waitUntilTableExists({ client, maxWaitTime: 300 }, { TableName: sharedTableName }); + }, 60000); + + afterAll(async () => { + // Cleanup shared table + if (sharedTableName) { + try { + await client.deleteTable({ TableName: sharedTableName }); + } catch (error) { + // Ignore errors during cleanup + } + } + }); + + describe("Creating a table", () => { + it("should verify table exists and is active", async () => { + // Verify table exists by describing it + const describeResult = await client.describeTable({ TableName: sharedTableName }); + expect(describeResult.Table?.TableName).toBe(sharedTableName); + expect(describeResult.Table?.TableStatus).toBe("ACTIVE"); + }); + }); + + describe("Item CRUD", () => { + it("should put item, get it, and verify attributes", async () => { + // Put item + const item = { id: { S: "foo" }, data: { S: "bår" } }; + const putResult = await client.putItem({ + TableName: sharedTableName, + Item: item, + }); + + expect(putResult.$metadata?.httpStatusCode).toBe(200); + + // Get item + const getResult = await client.getItem({ + TableName: sharedTableName, + Key: { id: { S: "foo" } }, + }); + + expect(getResult.Item?.id.S).toBe("foo"); + expect(getResult.Item?.data.S).toBe("bår"); + }); + }); + + describe("UTF-8 support", () => { + it("should handle UTF-8 characters and return ResourceNotFoundException for non-existent table", async () => { + await expect( + client.deleteItem({ + TableName: "table", + Key: { id: { S: "føø" } }, + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ResourceNotFoundException", + }) + ); + }); + }); + + describe("Improper table deletion", () => { + it("should return ValidationException for empty table parameter", async () => { + await expect(client.deleteTable({ TableName: "" })).rejects.toThrow( + expect.objectContaining({ + name: "ValidationException", + $metadata: expect.objectContaining({ + httpStatusCode: 400, + }), + }) + ); + }); + }); + + describe("Recursive Attributes", () => { + it("should handle complex nested attributes", async () => { + // Put recursive item + const recursiveItem = { + id: { S: "fooRecursive" }, + data: { + M: { + attr1: { + L: [{ S: "value1" }, { L: [{ M: { attr12: { S: "value2" } } }] }], + }, + attr2: { + L: [{ B: new Uint8Array([0]) }, { B: new Uint8Array([1]) }, { NULL: true }, { BOOL: true }], + }, + }, + }, + }; + + const putResult = await client.putItem({ + TableName: sharedTableName, + Item: recursiveItem, + }); + + expect(putResult.$metadata?.httpStatusCode).toBe(200); + + // Get item and verify nested attribute + const getResult = await client.getItem({ + TableName: sharedTableName, + Key: { id: { S: "fooRecursive" } }, + }); + + expect(getResult.$metadata?.httpStatusCode).toBe(200); + expect(getResult.Item?.id.S).toBe("fooRecursive"); + + // Verify deeply nested attribute: data.M.attr1.L[1].L[0].M.attr12.S + const nestedValue = getResult.Item?.data?.M?.attr1?.L?.[1]?.L?.[0]?.M?.attr12?.S; + expect(nestedValue).toBe("value2"); + }); + }); +}); diff --git a/clients/client-ecr/package.json b/clients/client-ecr/package.json index 2eebcad448d8..e73fe3a2e383 100644 --- a/clients/client-ecr/package.json +++ b/clients/client-ecr/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo ecr", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-ecr/test/ecr-features.e2e.spec.ts b/clients/client-ecr/test/ecr-features.e2e.spec.ts new file mode 100644 index 000000000000..ffce3911c36b --- /dev/null +++ b/clients/client-ecr/test/ecr-features.e2e.spec.ts @@ -0,0 +1,40 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { ECR } from "@aws-sdk/client-ecr"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon EC2 Container Registry Features", () => { + let client: ECR; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new ECR({ region }); + }); + + describe("Making a request", () => { + it("should successfully describe repositories", async () => { + const result = await client.describeRepositories({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.repositories)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain repository not found error for fake repository name", async () => { + await expect( + client.listImages({ + repositoryName: "fake_name", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "RepositoryNotFoundException", + }) + ); + }); + }); +}); diff --git a/clients/client-ecr/vitest.config.e2e.mts b/clients/client-ecr/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-ecr/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-ecs/package.json b/clients/client-ecs/package.json index de5987da1198..ecd451950fb4 100644 --- a/clients/client-ecs/package.json +++ b/clients/client-ecs/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo ecs", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-ecs/test/ecs-features.e2e.spec.ts b/clients/client-ecs/test/ecs-features.e2e.spec.ts new file mode 100644 index 000000000000..a5383149249d --- /dev/null +++ b/clients/client-ecs/test/ecs-features.e2e.spec.ts @@ -0,0 +1,42 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { ECS } from "@aws-sdk/client-ecs"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon ECS Features", () => { + let client: ECS; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new ECS({ region }); + }); + + describe("Listing clusters", () => { + it("should successfully list clusters", async () => { + const result = await client.listClusters({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.clusterArns)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should return 400 status code for invalid task", async () => { + await expect( + client.stopTask({ + task: "xxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxx", + }) + ).rejects.toThrow( + expect.objectContaining({ + $metadata: expect.objectContaining({ + httpStatusCode: 400, + }), + }) + ); + }); + }); +}); diff --git a/clients/client-ecs/vitest.config.e2e.mts b/clients/client-ecs/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-ecs/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-efs/package.json b/clients/client-efs/package.json index 58955070c49e..3cfd1887f1b6 100644 --- a/clients/client-efs/package.json +++ b/clients/client-efs/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo efs", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-efs/test/efs-features.e2e.spec.ts b/clients/client-efs/test/efs-features.e2e.spec.ts new file mode 100644 index 000000000000..a517b2d13179 --- /dev/null +++ b/clients/client-efs/test/efs-features.e2e.spec.ts @@ -0,0 +1,40 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { EFS } from "@aws-sdk/client-efs"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon Elastic File System Features", () => { + let client: EFS; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new EFS({ region }); + }); + + describe("Listing file systems", () => { + it("should successfully describe file systems", async () => { + const result = await client.describeFileSystems({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.FileSystems)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain validation error for fake file system ID", async () => { + await expect( + client.deleteFileSystem({ + FileSystemId: "fake-id", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationException", + }) + ); + }); + }); +}); diff --git a/clients/client-efs/vitest.config.e2e.mts b/clients/client-efs/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-efs/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-elastic-beanstalk/package.json b/clients/client-elastic-beanstalk/package.json index a0b847704311..acd340a563e5 100644 --- a/clients/client-elastic-beanstalk/package.json +++ b/clients/client-elastic-beanstalk/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo elastic-beanstalk", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-elastic-beanstalk/test/elasticbeanstalk-features.e2e.spec.ts b/clients/client-elastic-beanstalk/test/elasticbeanstalk-features.e2e.spec.ts new file mode 100644 index 000000000000..a99b100b2592 --- /dev/null +++ b/clients/client-elastic-beanstalk/test/elasticbeanstalk-features.e2e.spec.ts @@ -0,0 +1,75 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { ElasticBeanstalk } from "@aws-sdk/client-elastic-beanstalk"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("AWS Elastic Beanstalk Features", () => { + let client: ElasticBeanstalk; + let region: string; + let applicationName: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new ElasticBeanstalk({ region }); + }); + + describe("Creating applications and application versions", () => { + it("should create application, version, and describe them", async () => { + applicationName = `aws-js-sdk-${Date.now()}`; + + // Create Elastic Beanstalk application + const createAppResult = await client.createApplication({ + ApplicationName: applicationName, + Description: "Test application for SDK", + }); + + expect(createAppResult.Application?.ApplicationName).toBe(applicationName); + + // Create application version + const createVersionResult = await client.createApplicationVersion({ + ApplicationName: applicationName, + VersionLabel: "1.0.0", + Description: "Test version for SDK", + }); + + expect(createVersionResult.ApplicationVersion?.VersionLabel).toBe("1.0.0"); + + // Describe the application + const describeResult = await client.describeApplications({ + ApplicationNames: [applicationName], + }); + + // The result should contain the Elastic Beanstalk application name and version + expect(describeResult.Applications?.[0]?.ApplicationName).toBe(applicationName); + expect(describeResult.Applications?.[0]?.Versions).toContain("1.0.0"); + + // Cleanup - delete application version and application + await client.deleteApplicationVersion({ + ApplicationName: applicationName, + VersionLabel: "1.0.0", + }); + + await client.deleteApplication({ + ApplicationName: applicationName, + }); + }); + }); + + describe("Error handling", () => { + it("should contain validation error for empty application name", async () => { + await expect( + client.createApplication({ + ApplicationName: "", + Description: "Test application", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationError", + }) + ); + }); + }); +}); diff --git a/clients/client-elastic-beanstalk/vitest.config.e2e.mts b/clients/client-elastic-beanstalk/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-elastic-beanstalk/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-elastic-load-balancing-v2/package.json b/clients/client-elastic-load-balancing-v2/package.json index fecf2a3f14fe..cb00a802c35b 100644 --- a/clients/client-elastic-load-balancing-v2/package.json +++ b/clients/client-elastic-load-balancing-v2/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo elastic-load-balancing-v2", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-elastic-load-balancing-v2/test/elbv2-features.e2e.spec.ts b/clients/client-elastic-load-balancing-v2/test/elbv2-features.e2e.spec.ts new file mode 100644 index 000000000000..d4e43bef4eef --- /dev/null +++ b/clients/client-elastic-load-balancing-v2/test/elbv2-features.e2e.spec.ts @@ -0,0 +1,40 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { ElasticLoadBalancingV2 } from "@aws-sdk/client-elastic-load-balancing-v2"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Elastic Load Balancing v2 Features", () => { + let client: ElasticLoadBalancingV2; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new ElasticLoadBalancingV2({ region }); + }); + + describe("Making a request", () => { + it("should successfully describe target groups", async () => { + const result = await client.describeTargetGroups({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.TargetGroups)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain validation error for fake ARN", async () => { + await expect( + client.describeTags({ + ResourceArns: ["fake_arn"], + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationError", + }) + ); + }); + }); +}); diff --git a/clients/client-elastic-load-balancing-v2/vitest.config.e2e.mts b/clients/client-elastic-load-balancing-v2/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-elastic-load-balancing-v2/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-elastic-load-balancing/package.json b/clients/client-elastic-load-balancing/package.json index c607d53dac44..bdb30c04a141 100644 --- a/clients/client-elastic-load-balancing/package.json +++ b/clients/client-elastic-load-balancing/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo elastic-load-balancing", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-elastic-load-balancing/test/elb-features.e2e.spec.ts b/clients/client-elastic-load-balancing/test/elb-features.e2e.spec.ts new file mode 100644 index 000000000000..5305a1be78ba --- /dev/null +++ b/clients/client-elastic-load-balancing/test/elb-features.e2e.spec.ts @@ -0,0 +1,50 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { ElasticLoadBalancing } from "@aws-sdk/client-elastic-load-balancing"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Elastic Load Balancing Features", () => { + let client: ElasticLoadBalancing; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new ElasticLoadBalancing({ region }); + }); + + describe("Making a request", () => { + it("should successfully describe load balancers", async () => { + const result = await client.describeLoadBalancers({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + }); + }); + + describe("Error handling", () => { + it("should contain validation error for very long load balancer name", async () => { + await expect( + client.createLoadBalancer({ + LoadBalancerName: "verylongelasticloadbalancername", + Listeners: [ + { + Protocol: "HTTP", + LoadBalancerPort: 80, + InstancePort: 80, + }, + ], + AvailabilityZones: ["us-east-1a"], + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationError", + $metadata: expect.objectContaining({ + httpStatusCode: 400, + }), + }) + ); + }); + }); +}); diff --git a/clients/client-elastic-load-balancing/vitest.config.e2e.mts b/clients/client-elastic-load-balancing/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-elastic-load-balancing/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-elasticache/package.json b/clients/client-elasticache/package.json index 0a5c7fea0c9e..055f763ad40e 100644 --- a/clients/client-elasticache/package.json +++ b/clients/client-elasticache/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo elasticache", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-elasticache/test/elasticache-features.e2e.spec.ts b/clients/client-elasticache/test/elasticache-features.e2e.spec.ts new file mode 100644 index 000000000000..e91525026938 --- /dev/null +++ b/clients/client-elasticache/test/elasticache-features.e2e.spec.ts @@ -0,0 +1,65 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { ElastiCache } from "@aws-sdk/client-elasticache"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon ElastiCache Features", () => { + let client: ElastiCache; + let region: string; + let cacheParameterGroupName: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new ElastiCache({ region }); + }); + + describe("Creating and deleting cache parameter groups", () => { + it("should create, describe, and delete cache parameter group", async () => { + cacheParameterGroupName = `aws-js-sdk-${Date.now()}`; + + // Create cache parameter group + const createResult = await client.createCacheParameterGroup({ + CacheParameterGroupName: cacheParameterGroupName, + CacheParameterGroupFamily: "redis7", + Description: "Test parameter group for SDK", + }); + + expect(createResult.CacheParameterGroup?.CacheParameterGroupName).toBe(cacheParameterGroupName); + + // Describe cache parameter groups + const describeResult = await client.describeCacheParameterGroups({}); + + expect(Array.isArray(describeResult.CacheParameterGroups)).toBe(true); + + // Check if parameter group is in the list + const foundGroup = describeResult.CacheParameterGroups?.find( + (group) => group.CacheParameterGroupName === cacheParameterGroupName + ); + expect(foundGroup?.CacheParameterGroupName).toBe(cacheParameterGroupName); + + // Cleanup - delete the parameter group + await client.deleteCacheParameterGroup({ + CacheParameterGroupName: cacheParameterGroupName, + }); + }); + }); + + describe("Error handling", () => { + it("should contain invalid parameter error for empty parameter group name", async () => { + await expect( + client.createCacheParameterGroup({ + CacheParameterGroupName: "", + CacheParameterGroupFamily: "redis7", + Description: "Test parameter group", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "InvalidParameterValueException", + }) + ); + }); + }); +}); diff --git a/clients/client-elasticache/vitest.config.e2e.mts b/clients/client-elasticache/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-elasticache/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-elasticsearch-service/package.json b/clients/client-elasticsearch-service/package.json index 7b568996b48b..ee9a126cf7e9 100644 --- a/clients/client-elasticsearch-service/package.json +++ b/clients/client-elasticsearch-service/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo elasticsearch-service", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-elasticsearch-service/test/es-features.e2e.spec.ts b/clients/client-elasticsearch-service/test/es-features.e2e.spec.ts new file mode 100644 index 000000000000..c8dce88b3e88 --- /dev/null +++ b/clients/client-elasticsearch-service/test/es-features.e2e.spec.ts @@ -0,0 +1,40 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { ElasticsearchService } from "@aws-sdk/client-elasticsearch-service"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon ES Features", () => { + let client: ElasticsearchService; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new ElasticsearchService({ region }); + }); + + describe("Making a request", () => { + it("should successfully list domain names", async () => { + const result = await client.listDomainNames({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.DomainNames)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain resource not found error for non-existent domain", async () => { + await expect( + client.describeElasticsearchDomain({ + DomainName: "not-a-domain", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ResourceNotFoundException", + }) + ); + }); + }); +}); diff --git a/clients/client-elasticsearch-service/vitest.config.e2e.mts b/clients/client-elasticsearch-service/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-elasticsearch-service/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-emr/package.json b/clients/client-emr/package.json index 483619bc6e55..5ea0c4c62a31 100644 --- a/clients/client-emr/package.json +++ b/clients/client-emr/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo emr", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-emr/test/emr-features.e2e.spec.ts b/clients/client-emr/test/emr-features.e2e.spec.ts new file mode 100644 index 000000000000..2b4ef525c007 --- /dev/null +++ b/clients/client-emr/test/emr-features.e2e.spec.ts @@ -0,0 +1,41 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { EMR } from "@aws-sdk/client-emr"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon Elastic MapReduce Features", () => { + let client: EMR; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new EMR({ region }); + }); + + describe("Making a request", () => { + it("should successfully list clusters", async () => { + const result = await client.listClusters({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.Clusters)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain validation error for invalid parameters", async () => { + await expect( + client.runJobFlow({ + Name: "", // Empty name should cause ValidationException + Instances: {}, // Empty instances config + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationException", + }) + ); + }); + }); +}); diff --git a/clients/client-emr/vitest.config.e2e.mts b/clients/client-emr/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-emr/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-gamelift/package.json b/clients/client-gamelift/package.json index f0fb60cbf23c..e07e4d17b3df 100644 --- a/clients/client-gamelift/package.json +++ b/clients/client-gamelift/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo gamelift", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-gamelift/test/gamelift-features.e2e.spec.ts b/clients/client-gamelift/test/gamelift-features.e2e.spec.ts new file mode 100644 index 000000000000..002cf38747db --- /dev/null +++ b/clients/client-gamelift/test/gamelift-features.e2e.spec.ts @@ -0,0 +1,40 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { GameLift } from "@aws-sdk/client-gamelift"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon GameLift Features", () => { + let client: GameLift; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new GameLift({ region }); + }); + + describe("Making a request", () => { + it("should successfully list builds", async () => { + const result = await client.listBuilds({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.Builds)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain invalid request eexception for fake alias ID", async () => { + await expect( + client.describeAlias({ + AliasId: "fake_id", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "InvalidRequestException", + }) + ); + }); + }); +}); diff --git a/clients/client-gamelift/vitest.config.e2e.mts b/clients/client-gamelift/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-gamelift/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-glacier/package.json b/clients/client-glacier/package.json index 3240c6c4b570..81e42e93b4a9 100644 --- a/clients/client-glacier/package.json +++ b/clients/client-glacier/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo glacier", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-glacier/test/glacier-features.e2e.spec.ts b/clients/client-glacier/test/glacier-features.e2e.spec.ts new file mode 100644 index 000000000000..50d1b8f41447 --- /dev/null +++ b/clients/client-glacier/test/glacier-features.e2e.spec.ts @@ -0,0 +1,168 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { Glacier } from "@aws-sdk/client-glacier"; +import { afterAll, beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon Glacier Features", () => { + let client: Glacier; + let region: string; + let vaultName: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new Glacier({ region }); + vaultName = `aws-js-sdk-integration`; + + // Create vault + await client.createVault({ + accountId: "", + vaultName: vaultName, + }); + }); + + afterAll(async () => { + // Delete vault + try { + await client.deleteVault({ + accountId: "", + vaultName: vaultName, + }); + } catch (error) { + console.warn(`Could not delete vault ${vaultName}:`, (error as Error).message); + } + }); + + it("should describe vault with NumberOfArchives property", async () => { + const describeResult = await client.describeVault({ + accountId: "", + vaultName: vaultName, + }); + + expect(describeResult.NumberOfArchives).toBeDefined(); + expect(typeof describeResult.NumberOfArchives).toBe("number"); + }); + + it("should upload archive, verify checksum, and delete it", async () => { + // Create 0.25MB test data + const data = Buffer.alloc(0.25 * 1024 * 1024); + data.fill("0"); + + // Upload archive + const uploadResult = await client.uploadArchive({ + accountId: "", + vaultName: vaultName, + body: data, + }); + + expect(uploadResult.archiveId).toBeDefined(); + expect(uploadResult.checksum).toBeDefined(); + expect(uploadResult.checksum).toBe("6faefade5a638cd3545d638dd5754763658e32209e69420cb559b7650d4bf93a"); + + // Delete archive + const deleteResult = await client.deleteArchive({ + accountId: "", + vaultName: vaultName, + archiveId: uploadResult.archiveId!, + }); + + expect(deleteResult.$metadata?.httpStatusCode).toBe(204); + }); + + it("should complete multi-part upload with chunks", async () => { + // Setup multi-part upload: 2.5MB archive in 1MB chunks + const totalSize = 2.5 * 1024 * 1024; + const partSize = 1024 * 1024; // 1MB + const uploadData = Buffer.alloc(totalSize); + uploadData.fill("0"); + + // Initiate multi-part upload + const initiateResult = await client.initiateMultipartUpload({ + accountId: "", + vaultName: vaultName, + partSize: partSize.toString(), + }); + + expect(initiateResult.uploadId).toBeDefined(); + + const uploadId = initiateResult.uploadId!; + + // Upload parts + for (let i = 0; i < uploadData.length; i += partSize) { + const end = Math.min(i + partSize, uploadData.length); + const buf = uploadData.subarray(i, end); + const range = `bytes ${i}-${end - 1}/*`; + + await client.uploadMultipartPart({ + accountId: "", + vaultName: vaultName, + uploadId: uploadId, + range: range, + body: buf, + }); + } + + // Complete multi-part upload + const completeResult = await client.completeMultipartUpload({ + accountId: "", + vaultName: vaultName, + uploadId: uploadId, + archiveSize: uploadData.length.toString(), + checksum: "86118ad0c187fd240db59a37360e0e7f8a3a0c608eed740b4cd7b4271ab45171", + }); + + expect(completeResult.$metadata?.httpStatusCode).toBe(201); + expect(completeResult.archiveId).toBeDefined(); + expect(completeResult.checksum).toBeDefined(); + expect(completeResult.checksum).toBe("86118ad0c187fd240db59a37360e0e7f8a3a0c608eed740b4cd7b4271ab45171"); + + // Delete multipart archive + await client.deleteArchive({ + accountId: "", + vaultName: vaultName, + archiveId: completeResult.archiveId!, + }); + }); + + describe("Error handling", () => { + it("should throw InvalidParameterValueException for incorrect checksum", async () => { + const data = Buffer.alloc(0.05 * 1024 * 1024); + data.fill("0"); + + await expect( + client.uploadArchive({ + accountId: "", + vaultName: vaultName, + body: data, + checksum: "00000000000000000000000000000000", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "InvalidParameterValueException", + message: expect.stringContaining("Checksum mismatch"), + }) + ); + }); + + it("should throw InvalidParameterValueException for invalid checksum format", async () => { + const data = Buffer.alloc(0.05 * 1024 * 1024); + data.fill("0"); + + await expect( + client.uploadArchive({ + accountId: "", + vaultName: vaultName, + body: data, + checksum: "000", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "InvalidParameterValueException", + message: expect.stringContaining("Invalid x-amz-sha256-tree-hash: 000"), + }) + ); + }); + }); +}); diff --git a/clients/client-glacier/vitest.config.e2e.mts b/clients/client-glacier/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-glacier/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-iam/package.json b/clients/client-iam/package.json index 6ede907194ba..9662f6fdac70 100644 --- a/clients/client-iam/package.json +++ b/clients/client-iam/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo iam", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-iam/test/iam-features.e2e.spec.ts b/clients/client-iam/test/iam-features.e2e.spec.ts new file mode 100644 index 000000000000..92110c64c9e1 --- /dev/null +++ b/clients/client-iam/test/iam-features.e2e.spec.ts @@ -0,0 +1,67 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { IAM } from "@aws-sdk/client-iam"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("IAM Features", () => { + let client: IAM; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new IAM({ region }); + }); + + describe("Users", () => { + it("should create IAM user", async () => { + const username = `js-test-${Date.now()}`; + + const result = await client.createUser({ + UserName: username, + }); + + expect(result.User?.UserName).toBe(username); + + await client.deleteUser({ UserName: username }); + }); + }); + + describe("Roles", () => { + it("should create IAM role", async () => { + const roleName = `aws-sdk-js-${Date.now()}`; + + const result = await client.createRole({ + RoleName: roleName, + AssumeRolePolicyDocument: JSON.stringify({ + Version: "2012-10-17", + Statement: [{ Effect: "Allow", Principal: { Service: "ec2.amazonaws.com" }, Action: "sts:AssumeRole" }], + }), + }); + + expect(result.Role?.RoleName).toBe(roleName); + + await client.deleteRole({ RoleName: roleName }); + }); + }); + + describe("Error handling", () => { + it("should contain entity already exists error for duplicate user", async () => { + const username = `js-test-dupe-${Date.now()}`; + + await client.createUser({ UserName: username }); + + try { + await expect(client.createUser({ UserName: username })).rejects.toThrow( + expect.objectContaining({ + name: "EntityAlreadyExistsException", + }) + ); + } finally { + await client.deleteUser({ UserName: username }); + } + }); + }); +}); diff --git a/clients/client-iam/vitest.config.e2e.mts b/clients/client-iam/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-iam/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-iot/package.json b/clients/client-iot/package.json index 9929ee578b29..e4c0cf8f740c 100644 --- a/clients/client-iot/package.json +++ b/clients/client-iot/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo iot", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-iot/test/iot-features.e2e.spec.ts b/clients/client-iot/test/iot-features.e2e.spec.ts new file mode 100644 index 000000000000..8dc9d049307e --- /dev/null +++ b/clients/client-iot/test/iot-features.e2e.spec.ts @@ -0,0 +1,40 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { IoT } from "@aws-sdk/client-iot"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("AWS IoT Features", () => { + let client: IoT; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new IoT({ region }); + }); + + describe("Making a request", () => { + it("should successfully list policies", async () => { + const result = await client.listPolicies({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.policies)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain invalid request exception for fake certificate ID", async () => { + await expect( + client.describeCertificate({ + certificateId: "fake_id", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "InvalidRequestException", + }) + ); + }); + }); +}); diff --git a/clients/client-iot/vitest.config.e2e.mts b/clients/client-iot/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-iot/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-kinesis/test/kinesis-features.e2e.spec.ts b/clients/client-kinesis/test/kinesis-features.e2e.spec.ts new file mode 100644 index 000000000000..2bd5211e7193 --- /dev/null +++ b/clients/client-kinesis/test/kinesis-features.e2e.spec.ts @@ -0,0 +1,31 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { Kinesis } from "@aws-sdk/client-kinesis"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon Kinesis Features", () => { + let client: Kinesis; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new Kinesis({ region }); + }); + + describe("Error handling", () => { + it("should contain resource not found error for non-existent stream", async () => { + await expect( + client.describeStream({ + StreamName: "non-existent-stream", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ResourceNotFoundException", + }) + ); + }); + }); +}); diff --git a/clients/client-kinesis/vitest.config.e2e.mts b/clients/client-kinesis/vitest.config.e2e.mts index 92073c6cfcf0..ccea26a45905 100644 --- a/clients/client-kinesis/vitest.config.e2e.mts +++ b/clients/client-kinesis/vitest.config.e2e.mts @@ -2,7 +2,9 @@ import { defineConfig } from "vitest/config"; export default defineConfig({ test: { + exclude: ["**/*.browser.e2e.spec.ts"], include: ["**/*.e2e.spec.ts"], environment: "node", }, + mode: "development", }); diff --git a/clients/client-kms/package.json b/clients/client-kms/package.json index ef4ade6dbaaf..ee223a5615b1 100644 --- a/clients/client-kms/package.json +++ b/clients/client-kms/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo kms", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-kms/test/kms-features.e2e.spec.ts b/clients/client-kms/test/kms-features.e2e.spec.ts new file mode 100644 index 000000000000..07d979e9f77a --- /dev/null +++ b/clients/client-kms/test/kms-features.e2e.spec.ts @@ -0,0 +1,41 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { KMS } from "@aws-sdk/client-kms"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("AWS Key Management Service Features", () => { + let client: KMS; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new KMS({ region }); + }); + + describe("List keys", () => { + it("should successfully list keys", async () => { + const result = await client.listKeys({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.Keys)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain validation error for invalid alias creation", async () => { + await expect( + client.createAlias({ + AliasName: "alias", + TargetKeyId: "non-existent", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationException", + }) + ); + }); + }); +}); diff --git a/clients/client-kms/vitest.config.e2e.mts b/clients/client-kms/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-kms/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-lambda/package.json b/clients/client-lambda/package.json index 1d5bc49d70a6..dcbb06905e70 100644 --- a/clients/client-lambda/package.json +++ b/clients/client-lambda/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo lambda", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-lambda/test/lambda-features.e2e.spec.ts b/clients/client-lambda/test/lambda-features.e2e.spec.ts new file mode 100644 index 000000000000..ee6f39739b3c --- /dev/null +++ b/clients/client-lambda/test/lambda-features.e2e.spec.ts @@ -0,0 +1,40 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { Lambda } from "@aws-sdk/client-lambda"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon Lambda Features", () => { + let client: Lambda; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new Lambda({ region }); + }); + + describe("Listing functions", () => { + it("should successfully list functions", async () => { + const result = await client.listFunctions({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.Functions)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain resource not found error for non-existent function", async () => { + await expect( + client.invoke({ + FunctionName: "non-exist", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ResourceNotFoundException", + }) + ); + }); + }); +}); diff --git a/clients/client-lambda/vitest.config.e2e.mts b/clients/client-lambda/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-lambda/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-rds/package.json b/clients/client-rds/package.json index ae3eec59c1b2..a7e5035e3f43 100644 --- a/clients/client-rds/package.json +++ b/clients/client-rds/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo rds", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-rds/test/rds-features.e2e.spec.ts b/clients/client-rds/test/rds-features.e2e.spec.ts new file mode 100644 index 000000000000..947d48a70f72 --- /dev/null +++ b/clients/client-rds/test/rds-features.e2e.spec.ts @@ -0,0 +1,100 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { paginateDescribeReservedDBInstancesOfferings, RDS } from "@aws-sdk/client-rds"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon Relational Database Service Features", () => { + let client: RDS; + let region: string; + let dbSecurityGroupName: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new RDS({ region }); + }); + + describe("Describe DB security group", () => { + it("should create security group, describe it, and verify structure", async () => { + dbSecurityGroupName = `aws-sdk-js-rds-e2e`; + + const expectedDescription = "Test security group for e2e tests"; + + // Create RDS security group + const createResult = await client.createDBSecurityGroup({ + DBSecurityGroupName: dbSecurityGroupName, + DBSecurityGroupDescription: expectedDescription, + }); + + expect(createResult.$metadata?.httpStatusCode).toBe(200); + expect(createResult.DBSecurityGroup?.DBSecurityGroupName).toBe(dbSecurityGroupName); + + // Describe DB security groups + const describeResult = await client.describeDBSecurityGroups({}); + + expect(describeResult.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(describeResult.DBSecurityGroups)).toBe(true); + + // Verify the security group contains the DBSecurityGroupDescription + const foundGroup = describeResult.DBSecurityGroups?.find( + (group) => group.DBSecurityGroupName === dbSecurityGroupName + ); + + expect(foundGroup?.DBSecurityGroupDescription).toBe(expectedDescription); + + // Cleanup - delete security group + await client.deleteDBSecurityGroup({ + DBSecurityGroupName: dbSecurityGroupName, + }); + }); + }); + + describe("Error handling", () => { + it("should get InvalidParameterValue with 400 status for empty security group name", async () => { + try { + await client.createDBSecurityGroup({ + DBSecurityGroupName: "", // Empty name should cause InvalidParameterValue + DBSecurityGroupDescription: "Test security group", + }); + } catch (error: any) { + expect(error.name).toBe("InvalidParameterValue"); + expect(error.$metadata?.httpStatusCode).toBe(400); + } + }); + }); + + describe("Paginating responses", () => { + it("should paginate describeReservedDBInstancesOfferings with more than one page", async () => { + const maxPages = 3; + const limit = 100; + let numPages = 0; + let numMarkers = 0; + + const paginator = paginateDescribeReservedDBInstancesOfferings( + { + client, + pageSize: limit, + }, + {} + ); + + for await (const page of paginator) { + numPages++; + if (page.Marker) { + numMarkers++; + } + + // Stop after maxPages to avoid long test execution + if (numPages >= maxPages) { + break; + } + } + + // Should get more than one page + expect(numPages).toBeGreaterThan(1); + expect(numMarkers).toBeGreaterThan(0); + }); + }); +}); diff --git a/clients/client-rds/vitest.config.e2e.mts b/clients/client-rds/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-rds/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-redshift/package.json b/clients/client-redshift/package.json index cd86a1a496d2..3cc4198afa0b 100644 --- a/clients/client-redshift/package.json +++ b/clients/client-redshift/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo redshift", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-redshift/test/redshift-features.e2e.spec.ts b/clients/client-redshift/test/redshift-features.e2e.spec.ts new file mode 100644 index 000000000000..ed5b0b31b36f --- /dev/null +++ b/clients/client-redshift/test/redshift-features.e2e.spec.ts @@ -0,0 +1,41 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { Redshift } from "@aws-sdk/client-redshift"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon Redshift Features", () => { + let client: Redshift; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new Redshift({ region }); + }); + + describe("Describe cluster parameter groups", () => { + it("should successfully describe cluster parameter groups", async () => { + const result = await client.describeClusterParameterGroups({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.ParameterGroups)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain invalid parameter error for empty parameter group name", async () => { + try { + await client.createClusterParameterGroup({ + ParameterGroupName: "", // Empty name should cause InvalidParameterValue + ParameterGroupFamily: "redshift-1.0", + Description: "Test parameter group", + }); + } catch (error: any) { + expect(error.name).toBe("InvalidParameterValue"); + expect(error.message).toContain("The parameter DBParameterGroupName must be provided and must not be blank"); + } + }); + }); +}); diff --git a/clients/client-redshift/vitest.config.e2e.mts b/clients/client-redshift/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-redshift/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-route-53-domains/package.json b/clients/client-route-53-domains/package.json index 9f55759daf31..71a89838ceb3 100644 --- a/clients/client-route-53-domains/package.json +++ b/clients/client-route-53-domains/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo route-53-domains", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-route-53-domains/test/route53domains-features.e2e.spec.ts b/clients/client-route-53-domains/test/route53domains-features.e2e.spec.ts new file mode 100644 index 000000000000..3e1bbe469a8e --- /dev/null +++ b/clients/client-route-53-domains/test/route53domains-features.e2e.spec.ts @@ -0,0 +1,54 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { Route53Domains } from "@aws-sdk/client-route-53-domains"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon Route 53 Domains Features", () => { + let client: Route53Domains; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + // Requests for domain registration only available in us-east-1 + region = "us-east-1"; + + client = new Route53Domains({ region }); + }); + + describe("Feature", () => { + it("should successfully list Route53 domains", async () => { + const result = await client.listDomains({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.Domains)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain invalid input error for invalid domain registration parameters", async () => { + await expect( + client.registerDomain({ + DomainName: "", // Empty domain name should cause InvalidInput + DurationInYears: 1, + AdminContact: { + FirstName: "", + LastName: "", + }, + RegistrantContact: { + FirstName: "", + LastName: "", + }, + TechContact: { + FirstName: "", + LastName: "", + }, + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "InvalidInput", + }) + ); + }); + }); +}); diff --git a/clients/client-route-53-domains/vitest.config.e2e.mts b/clients/client-route-53-domains/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-route-53-domains/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-route-53/package.json b/clients/client-route-53/package.json index 40a925b40814..8a5e1b082413 100644 --- a/clients/client-route-53/package.json +++ b/clients/client-route-53/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo route-53", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-route-53/test/route53-features.e2e.spec.ts b/clients/client-route-53/test/route53-features.e2e.spec.ts new file mode 100644 index 000000000000..51e508cb26ac --- /dev/null +++ b/clients/client-route-53/test/route53-features.e2e.spec.ts @@ -0,0 +1,40 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { Route53 } from "@aws-sdk/client-route-53"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon Route 53 Features", () => { + let client: Route53; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new Route53({ region }); + }); + + describe("Making a request", () => { + it("should successfully list hosted zones", async () => { + const result = await client.listHostedZones({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.HostedZones)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain no such hosted zone error for fake zone ID", async () => { + await expect( + client.getHostedZone({ + Id: "fake-zone", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "NoSuchHostedZone", + }) + ); + }); + }); +}); diff --git a/clients/client-route-53/vitest.config.e2e.mts b/clients/client-route-53/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-route-53/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-sagemaker/package.json b/clients/client-sagemaker/package.json index ca7d2cdf0077..df5cbb85360a 100644 --- a/clients/client-sagemaker/package.json +++ b/clients/client-sagemaker/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo sagemaker", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-sagemaker/test/sagemaker-features.e2e.spec.ts b/clients/client-sagemaker/test/sagemaker-features.e2e.spec.ts new file mode 100644 index 000000000000..839752bd1044 --- /dev/null +++ b/clients/client-sagemaker/test/sagemaker-features.e2e.spec.ts @@ -0,0 +1,40 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { SageMaker } from "@aws-sdk/client-sagemaker"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon SageMaker Features", () => { + let client: SageMaker; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new SageMaker({ region }); + }); + + describe("List Endpoints", () => { + it("should successfully list endpoints", async () => { + const result = await client.listEndpoints({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.Endpoints)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain validation error for non-existent endpoint", async () => { + await expect( + client.describeEndpoint({ + EndpointName: "non-existent", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationException", + }) + ); + }); + }); +}); diff --git a/clients/client-sagemaker/vitest.config.e2e.mts b/clients/client-sagemaker/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-sagemaker/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-ses/package.json b/clients/client-ses/package.json index ecc543e3447a..e0d1372d249c 100644 --- a/clients/client-ses/package.json +++ b/clients/client-ses/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo ses", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-ses/test/ses-features.e2e.spec.ts b/clients/client-ses/test/ses-features.e2e.spec.ts new file mode 100644 index 000000000000..f974f417359b --- /dev/null +++ b/clients/client-ses/test/ses-features.e2e.spec.ts @@ -0,0 +1,52 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { SES } from "@aws-sdk/client-ses"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("SES Features", () => { + let client: SES; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new SES({ region }); + }); + + describe("Check quota", () => { + it("should return quota with SentLast24Hours and MaxSendRate", async () => { + const result = await client.getSendQuota({}); + + expect(result.SentLast24Hours).toBeDefined(); + expect(typeof result.SentLast24Hours).toBe("number"); + expect(result.MaxSendRate).toBeDefined(); + expect(typeof result.MaxSendRate).toBe("number"); + }); + }); + + describe("Verify email", () => { + it("should return 200 status code for email verification request", async () => { + const result = await client.verifyEmailIdentity({ + EmailAddress: "foo@example.com", + }); + + expect(result.$metadata?.httpStatusCode).toBe(200); + }); + }); + + describe("Rescue SES InvalidParameterValue", () => { + it("should get InvalidParameterValue error for invalid email address", async () => { + try { + await client.verifyEmailIdentity({ + EmailAddress: "abc123", + }); + expect.fail("Expected InvalidParameterValue error was not thrown"); + } catch (error: any) { + expect(error.name).toBe("InvalidParameterValue"); + expect(error.message).toContain("Invalid email address."); + } + }); + }); +}); diff --git a/clients/client-ses/vitest.config.e2e.mts b/clients/client-ses/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-ses/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-sns/package.json b/clients/client-sns/package.json index df5c29723267..c612f2dab359 100644 --- a/clients/client-sns/package.json +++ b/clients/client-sns/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo sns", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-sns/test/sns-features.e2e.spec.ts b/clients/client-sns/test/sns-features.e2e.spec.ts new file mode 100644 index 000000000000..a8c223ddf346 --- /dev/null +++ b/clients/client-sns/test/sns-features.e2e.spec.ts @@ -0,0 +1,49 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { SNS } from "@aws-sdk/client-sns"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Simple Notification Service Features", () => { + let client: SNS; + let region: string; + let topicArn: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new SNS({ region }); + }); + + describe("Topics", () => { + it("should create and list SNS topics", async () => { + const createResult = await client.createTopic({ + Name: `aws-js-sdk-${Date.now()}`, + }); + + topicArn = createResult.TopicArn || ""; + expect(topicArn).toBeTruthy(); + + const listResult = await client.listTopics({}); + expect(Array.isArray(listResult.Topics)).toBe(true); + + // Cleanup + await client.deleteTopic({ TopicArn: topicArn }); + }); + }); + + describe("Error handling", () => { + it("should contain invalid parameter error for invalid ARN", async () => { + await expect( + client.getTopicAttributes({ + TopicArn: "invalid-arn", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "InvalidParameterException", + }) + ); + }); + }); +}); diff --git a/clients/client-sns/vitest.config.e2e.mts b/clients/client-sns/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-sns/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-sqs/test/sqs-messages-features.e2e.spec.ts b/clients/client-sqs/test/sqs-messages-features.e2e.spec.ts new file mode 100644 index 000000000000..0ad1c8ab5d3c --- /dev/null +++ b/clients/client-sqs/test/sqs-messages-features.e2e.spec.ts @@ -0,0 +1,95 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { SQS } from "@aws-sdk/client-sqs"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("SQS Messages", () => { + let client: SQS; + let region: string; + let queueUrl: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new SQS({ region }); + }); + + describe("Send an SQS message", () => { + it("should send message with correct MD5 and receive it", async () => { + // Create queue + const createResult = await client.createQueue({ + QueueName: `aws-js-sdk-${Date.now()}`, + }); + + queueUrl = createResult.QueueUrl || ""; + + // Send message "HELLO" + const sendResult = await client.sendMessage({ + QueueUrl: queueUrl, + MessageBody: "HELLO", + }); + + // Result should include a message ID + expect(sendResult.MessageId!.length).toBeGreaterThan(0); + + // Result should have MD5 digest of "eb61eead90e3b899c6bcbe27ac581660" + expect(sendResult.MD5OfMessageBody).toBe("eb61eead90e3b899c6bcbe27ac581660"); + + // Eventually receive "HELLO" from the queue + const receiveResult = await client.receiveMessage({ + QueueUrl: queueUrl, + }); + + expect(receiveResult.Messages?.[0]?.Body).toBe("HELLO"); + + // Cleanup + await client.deleteQueue({ QueueUrl: queueUrl }); + }); + }); + + describe("Binary payloads", () => { + it("should send message with binary attribute", async () => { + // Create queue + const createResult = await client.createQueue({ + QueueName: `aws-js-sdk-${Date.now()}`, + }); + + queueUrl = createResult.QueueUrl || ""; + + // Send message "HELLO" with binary attribute. + const sendResult = await client.sendMessage({ + QueueUrl: queueUrl, + MessageBody: "HELLO", + MessageAttributes: { + binary: { + DataType: "Binary", + BinaryValue: Buffer.from([1, 2, 3]), + }, + }, + }); + + // Result should include a message ID + expect(sendResult.MessageId!.length).toBeGreaterThan(0); + + // Result should have MD5 digest of "eb61eead90e3b899c6bcbe27ac581660" + expect(sendResult.MD5OfMessageBody).toBe("eb61eead90e3b899c6bcbe27ac581660"); + + // Eventually receive "HELLO" from the queue with binary attribute + const receiveResult = await client.receiveMessage({ + QueueUrl: queueUrl, + MessageAttributeNames: ["binary"], + }); + + expect(receiveResult.Messages?.[0]?.Body).toBe("HELLO"); + + // Verify binary attribute matches original: "1,2,3" + const binaryValue = receiveResult.Messages?.[0]?.MessageAttributes?.binary?.BinaryValue; + expect(binaryValue!.toString()).toBe("1,2,3"); + + // Cleanup + await client.deleteQueue({ QueueUrl: queueUrl }); + }); + }); +}); diff --git a/clients/client-sqs/test/sqs-queues-features.e2e.spec.ts b/clients/client-sqs/test/sqs-queues-features.e2e.spec.ts new file mode 100644 index 000000000000..5e036a070de2 --- /dev/null +++ b/clients/client-sqs/test/sqs-queues-features.e2e.spec.ts @@ -0,0 +1,57 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { SQS } from "@aws-sdk/client-sqs"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("SQS Queues", () => { + let client: SQS; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new SQS({ region }); + }); + + describe("Creating and deleting queues", () => { + it("should create queues and eventually list them", async () => { + const createdQueues: string[] = []; + + try { + // Create first queue + const createResult1 = await client.createQueue({ + QueueName: `aws-js-sdk-${Date.now()}`, + }); + const queueUrl1 = createResult1.QueueUrl!; + createdQueues.push(queueUrl1); + + // Create second queue + const createResult2 = await client.createQueue({ + QueueName: `aws-js-sdk-${Date.now() + 1}`, + }); + const queueUrl2 = createResult2.QueueUrl!; + createdQueues.push(queueUrl2); + + // List queues should contain the created queues + const listResult = await client.listQueues({}); + const queueUrls = listResult.QueueUrls || []; + + // Check that created queues exist in the list + for (const createdQueue of createdQueues) { + expect(queueUrls).toContain(createdQueue); + } + } finally { + // Cleanup + for (const queueUrl of createdQueues) { + try { + await client.deleteQueue({ QueueUrl: queueUrl }); + } catch (error) { + console.warn(`Failed to delete queue ${queueUrl}:`, error); + } + } + } + }); + }); +}); diff --git a/clients/client-ssm/package.json b/clients/client-ssm/package.json index 7e3a270339fb..6359f89bc296 100644 --- a/clients/client-ssm/package.json +++ b/clients/client-ssm/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo ssm", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-ssm/test/ssm-features.e2e.spec.ts b/clients/client-ssm/test/ssm-features.e2e.spec.ts new file mode 100644 index 000000000000..d8c57ba00d8b --- /dev/null +++ b/clients/client-ssm/test/ssm-features.e2e.spec.ts @@ -0,0 +1,40 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { SSM } from "@aws-sdk/client-ssm"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("AWS Simple Systems Management Features", () => { + let client: SSM; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new SSM({ region }); + }); + + describe("Listing Documents", () => { + it("should successfully list documents", async () => { + const result = await client.listDocuments({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.DocumentIdentifiers)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain invalid document error for non-existent document", async () => { + await expect( + client.describeDocument({ + Name: "foo-bar-baz", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "InvalidDocument", + }) + ); + }); + }); +}); diff --git a/clients/client-ssm/vitest.config.e2e.mts b/clients/client-ssm/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-ssm/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-storage-gateway/package.json b/clients/client-storage-gateway/package.json index d1a8dc911cec..4bcdadc44c26 100644 --- a/clients/client-storage-gateway/package.json +++ b/clients/client-storage-gateway/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo storage-gateway", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-storage-gateway/test/storagegateway-features.e2e.spec.ts b/clients/client-storage-gateway/test/storagegateway-features.e2e.spec.ts new file mode 100644 index 000000000000..685126157926 --- /dev/null +++ b/clients/client-storage-gateway/test/storagegateway-features.e2e.spec.ts @@ -0,0 +1,46 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { StorageGateway } from "@aws-sdk/client-storage-gateway"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("AWS Storage Gateway Features", () => { + let client: StorageGateway; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new StorageGateway({ region }); + }); + + describe("Listing Gateways", () => { + it("should successfully list gateways", async () => { + const result = await client.listGateways({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.Gateways)).toBe(true); + }); + }); + + describe("Activating a Gateway", () => { + it("should get InvalidGatewayRequestException with 400 status when trying to activate", async () => { + await expect( + client.activateGateway({ + ActivationKey: "INVALIDKEY", + GatewayName: `aws-sdk-js-${Date.now()}`, + GatewayTimezone: "GMT-5:00", + GatewayRegion: "us-east-1", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "InvalidGatewayRequestException", + $metadata: expect.objectContaining({ + httpStatusCode: 400, + }), + }) + ); + }); + }); +}); diff --git a/clients/client-storage-gateway/vitest.config.e2e.mts b/clients/client-storage-gateway/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-storage-gateway/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-sts/package.json b/clients/client-sts/package.json index cc273d8ff5b7..a80122e4e2e3 100644 --- a/clients/client-sts/package.json +++ b/clients/client-sts/package.json @@ -13,6 +13,8 @@ "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo sts", "test": "yarn g:vitest run", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs", "test:watch": "yarn g:vitest watch" }, diff --git a/clients/client-sts/test/sts-features.e2e.spec.ts b/clients/client-sts/test/sts-features.e2e.spec.ts new file mode 100644 index 000000000000..0268cb0748b0 --- /dev/null +++ b/clients/client-sts/test/sts-features.e2e.spec.ts @@ -0,0 +1,42 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { STS } from "@aws-sdk/client-sts"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("AWS Security Token Service Features", () => { + let client: STS; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new STS({ region }); + }); + + describe("Get caller identity", () => { + it("should return caller identity with Account, Arn, and UserId", async () => { + const result = await client.getCallerIdentity({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(typeof result.Account).toBe("string"); + expect(typeof result.Arn).toBe("string"); + expect(typeof result.UserId).toBe("string"); + }); + }); + + describe("Error handling", () => { + it("should contain validation error for invalid session token duration", async () => { + await expect( + client.getSessionToken({ + DurationSeconds: 60, + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationError", + }) + ); + }); + }); +}); diff --git a/clients/client-sts/vitest.config.e2e.mts b/clients/client-sts/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-sts/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-swf/package.json b/clients/client-swf/package.json index 3608db662193..27154c426328 100644 --- a/clients/client-swf/package.json +++ b/clients/client-swf/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo swf", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-swf/test/swf-features.e2e.spec.ts b/clients/client-swf/test/swf-features.e2e.spec.ts new file mode 100644 index 000000000000..6916596027fc --- /dev/null +++ b/clients/client-swf/test/swf-features.e2e.spec.ts @@ -0,0 +1,42 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { SWF } from "@aws-sdk/client-swf"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon Simple Workflow Service Features", () => { + let client: SWF; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new SWF({ region }); + }); + + describe("Listing domains", () => { + it("should successfully list registered domains", async () => { + const result = await client.listDomains({ + registrationStatus: "REGISTERED", + }); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.domainInfos)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain unknown resource fault for fake domain", async () => { + await expect( + client.describeDomain({ + name: "fake-domain", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "UnknownResourceFault", + }) + ); + }); + }); +}); diff --git a/clients/client-swf/vitest.config.e2e.mts b/clients/client-swf/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-swf/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-waf/package.json b/clients/client-waf/package.json index c591dbf61a7d..8e8726ce712e 100644 --- a/clients/client-waf/package.json +++ b/clients/client-waf/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo waf", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-waf/test/waf-features.e2e.spec.ts b/clients/client-waf/test/waf-features.e2e.spec.ts new file mode 100644 index 000000000000..59c4062bc466 --- /dev/null +++ b/clients/client-waf/test/waf-features.e2e.spec.ts @@ -0,0 +1,43 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { WAF } from "@aws-sdk/client-waf"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("AWS WAF Features", () => { + let client: WAF; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new WAF({ region }); + }); + + describe("Making a request", () => { + it("should successfully list rules", async () => { + const result = await client.listRules({ + Limit: 20, + }); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.Rules)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain WAF stale data exception for fake token", async () => { + await expect( + client.createSqlInjectionMatchSet({ + Name: "fake_name", + ChangeToken: "fake_token", + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "WAFStaleDataException", + }) + ); + }); + }); +}); diff --git a/clients/client-waf/vitest.config.e2e.mts b/clients/client-waf/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-waf/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/clients/client-workspaces/package.json b/clients/client-workspaces/package.json index ed7b99bb97da..ac3e5525e90f 100644 --- a/clients/client-workspaces/package.json +++ b/clients/client-workspaces/package.json @@ -12,6 +12,8 @@ "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "extract:docs": "api-extractor run --local", "generate:client": "node ../../scripts/generate-clients/single-service --solo workspaces", + "test:e2e": "yarn g:vitest run -c vitest.config.e2e.mts --mode development", + "test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.mts", "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs" }, "main": "./dist-cjs/index.js", diff --git a/clients/client-workspaces/test/workspaces-features.e2e.spec.ts b/clients/client-workspaces/test/workspaces-features.e2e.spec.ts new file mode 100644 index 000000000000..d85ad045f1cd --- /dev/null +++ b/clients/client-workspaces/test/workspaces-features.e2e.spec.ts @@ -0,0 +1,40 @@ +import { getE2eTestResources } from "@aws-sdk/aws-util-test/src"; +import { WorkSpaces } from "@aws-sdk/client-workspaces"; +import { beforeAll, describe, expect, test as it } from "vitest"; + +describe("Amazon WorkSpaces Features", () => { + let client: WorkSpaces; + let region: string; + + beforeAll(async () => { + const e2eTestResourcesEnv = await getE2eTestResources(); + Object.assign(process.env, e2eTestResourcesEnv); + + region = process?.env?.AWS_SMOKE_TEST_REGION as string; + + client = new WorkSpaces({ region }); + }); + + describe("Describing workspaces", () => { + it("should successfully describe workspaces", async () => { + const result = await client.describeWorkspaces({}); + + expect(result.$metadata?.httpStatusCode).toBe(200); + expect(Array.isArray(result.Workspaces)).toBe(true); + }); + }); + + describe("Error handling", () => { + it("should contain validation error for empty rebuild requests", async () => { + await expect( + client.rebuildWorkspaces({ + RebuildWorkspaceRequests: [], + }) + ).rejects.toThrow( + expect.objectContaining({ + name: "ValidationException", + }) + ); + }); + }); +}); diff --git a/clients/client-workspaces/vitest.config.e2e.mts b/clients/client-workspaces/vitest.config.e2e.mts new file mode 100644 index 000000000000..ccea26a45905 --- /dev/null +++ b/clients/client-workspaces/vitest.config.e2e.mts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["**/*.browser.e2e.spec.ts"], + include: ["**/*.e2e.spec.ts"], + environment: "node", + }, + mode: "development", +}); diff --git a/cucumber.json b/cucumber.json deleted file mode 100644 index 542cbe665310..000000000000 --- a/cucumber.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "default": { - "publishQuiet": true - } -} diff --git a/features/acm/acm.feature b/features/acm/acm.feature deleted file mode 100644 index 7da9679fd9f1..000000000000 --- a/features/acm/acm.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@acm -Feature: - - I want to use AWS Certificate Manager - - Scenario: Making a request - Given I run the "listCertificates" operation - Then the request should be successful - And the value at "CertificateSummaryList" should be a list - - Scenario: Error handling - Given I run the "describeCertificate" operation with params: - """ - { "CertificateArn": "fake_arn" } - """ - Then the error code should be "ValidationException" diff --git a/features/acm/step_definitions/acm.js b/features/acm/step_definitions/acm.js deleted file mode 100644 index 303fb3edcd79..000000000000 --- a/features/acm/step_definitions/acm.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@acm" }, function (scenario, callback) { - const { ACM } = require("../../../clients/client-acm"); - this.service = new ACM({}); - callback(); -}); diff --git a/features/apigateway/apigateway.feature b/features/apigateway/apigateway.feature deleted file mode 100644 index 663d7ee2630f..000000000000 --- a/features/apigateway/apigateway.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@apigateway -Feature: - - I want to use Amazon API Gateway - - Scenario: Making a request - Given I run the "getRestApis" operation - Then the request should be successful - And the value at "items" should be a list - - Scenario: Error handling - Given I run the "getRestApi" operation with params: - """ - { "restApiId": "fake_id" } - """ - Then the error code should be "NotFoundException" diff --git a/features/apigateway/step_definitions/apigateway.js b/features/apigateway/step_definitions/apigateway.js deleted file mode 100644 index c63db04e63f6..000000000000 --- a/features/apigateway/step_definitions/apigateway.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@apigateway" }, function (scenario, callback) { - const { APIGateway } = require("../../../clients/client-api-gateway"); - this.service = new APIGateway({}); - callback(); -}); diff --git a/features/cloudformation/cloudformation.feature b/features/cloudformation/cloudformation.feature deleted file mode 100644 index 1a13a19cd2f8..000000000000 --- a/features/cloudformation/cloudformation.feature +++ /dev/null @@ -1,20 +0,0 @@ -# language: en -@cloudformation -Feature: AWS CloudFormation - - I want to use AWS CloudFormation - - Scenario: Describing stacks - Given I run the "describeStacks" operation - Then the request should be successful - And the value at "Stacks" should be a list - - Scenario: Error handling - Given I create a CloudFormation stack with name prefix "" - Then the error code should be "ValidationError" - -# @pagination -# Scenario: Paginating responses -# Given I paginate the "listStacks" operation -# Then I should get at least one page -# And the last page should not contain a marker diff --git a/features/cloudformation/step_definitions/cloudformation.js b/features/cloudformation/step_definitions/cloudformation.js deleted file mode 100644 index 20603de1b6a2..000000000000 --- a/features/cloudformation/step_definitions/cloudformation.js +++ /dev/null @@ -1,18 +0,0 @@ -const { Before, Given } = require("@cucumber/cucumber"); - -Before({ tags: "@cloudformation" }, function (scenario, callback) { - const { CloudFormation } = require("../../../clients/client-cloudformation"); - this.service = new CloudFormation({}); - callback(); -}); - -Given("I create a CloudFormation stack with name prefix {string}", function (prefix, callback) { - this.stackName = this.uniqueName(prefix); - this.templateBody = '{"Resources":{"member":{"Type":"AWS::SQS::Queue"}}}'; - const params = { - TemplateBody: this.templateBody, - StackName: this.stackName, - EnableTerminationProtection: true, - }; - this.request(null, "createStack", params, callback, false); -}); diff --git a/features/cloudfront/cloudfront.feature b/features/cloudfront/cloudfront.feature deleted file mode 100644 index 9ffd92f4e780..000000000000 --- a/features/cloudfront/cloudfront.feature +++ /dev/null @@ -1,20 +0,0 @@ -# language: en -@cloudfront -Feature: Amazon CloudFront - - I want to use Amazon CloudFront - - Scenario: Listing distributions - Given I list CloudFront distributions - Then the result at DistributionList should contain a property Quantity with a number - - # Let this fail with NoSuchOrigin to confirm we serialized inputs - # but without creating a distribution. - Scenario: Creating a distribution - Given I create a CloudFront distribution with name prefix "aws-js-sdk" - Then the error code should be "NoSuchOrigin" - And the error status code should be 404 - - Scenario: Error handling - Given I create a CloudFront distribution with name prefix "" - Then the error code should be "InvalidArgument" diff --git a/features/cloudfront/step_definitions/cloudfront.js b/features/cloudfront/step_definitions/cloudfront.js deleted file mode 100644 index 977384dcae71..000000000000 --- a/features/cloudfront/step_definitions/cloudfront.js +++ /dev/null @@ -1,71 +0,0 @@ -const { Before, Given } = require("@cucumber/cucumber"); - -const createParams = { - CallerReference: "", - Aliases: { - Quantity: 0, - }, - DefaultRootObject: "", - Origins: { - Items: [ - { - Id: "origin", - DomainName: "example.com", - CustomOriginConfig: { - HTTPPort: 80, - HTTPSPort: 443, - OriginProtocolPolicy: "match-viewer", - }, - }, - ], - Quantity: 1, - }, - DefaultCacheBehavior: { - TargetOriginId: "origin", - ForwardedValues: { - QueryString: false, - Cookies: { - Forward: "all", - }, - }, - TrustedSigners: { - Items: [], - Enabled: false, - Quantity: 0, - }, - ViewerProtocolPolicy: "allow-all", - MinTTL: 0, - }, - CacheBehaviors: { - Items: [], - Quantity: 0, - }, - Comment: "", - Logging: { - Enabled: false, - Bucket: "invalidbucket.s3.amazonaws.com", - Prefix: "prefix", - IncludeCookies: false, - }, - PriceClass: "PriceClass_All", - Enabled: false, -}; - -Before({ tags: "@cloudfront" }, function (scenario, callback) { - const { CloudFront } = require("../../../clients/client-cloudfront"); - this.service = new CloudFront({}); - - this.cfCreateParams = createParams; - callback(); -}); - -Given("I create a CloudFront distribution with name prefix {string}", function (prefix, callback) { - this.cfName = this.uniqueName(prefix); - this.cfCreateParams.CallerReference = this.cfName; - this.cfCreateParams.Origins.Items[0].Id = this.cfName === "" ? "origin" : "InvalidOrigin"; - this.request(null, "createDistribution", { DistributionConfig: this.cfCreateParams }, callback, false); -}); - -Given("I list CloudFront distributions", function (callback) { - this.request(null, "listDistributions", {}, callback); -}); diff --git a/features/cloudtrail/cloudtrail.feature b/features/cloudtrail/cloudtrail.feature deleted file mode 100644 index c4d0f74f8918..000000000000 --- a/features/cloudtrail/cloudtrail.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@cloudtrail -Feature: AWS CloudTrail - - I want to use AWS CloudTrail - - Scenario: Describing trails - Given I describe trails - Then the status code should be 200 - - Scenario: Error handling - Given I create a trail with an invalid name - Then the error code should be "InvalidTrailNameException" - And the error message should contain: - """ - cannot be blank - """ diff --git a/features/cloudtrail/step_definitions/cloudtrail.js b/features/cloudtrail/step_definitions/cloudtrail.js deleted file mode 100644 index 3dff3316456e..000000000000 --- a/features/cloudtrail/step_definitions/cloudtrail.js +++ /dev/null @@ -1,15 +0,0 @@ -const { Before, Given } = require("@cucumber/cucumber"); - -Before({ tags: "@cloudtrail" }, function (scenario, callback) { - const { CloudTrail } = require("../../../clients/client-cloudtrail"); - this.service = new CloudTrail({}); - callback(); -}); - -Given("I describe trails", function (callback) { - this.request(null, "describeTrails", {}, callback); -}); - -Given("I create a trail with an invalid name", function (callback) { - this.request(null, "createTrail", { Name: "", S3BucketName: "" }, callback, false); -}); diff --git a/features/cloudwatch/cloudwatch.feature b/features/cloudwatch/cloudwatch.feature deleted file mode 100644 index b9a0bf51ff59..000000000000 --- a/features/cloudwatch/cloudwatch.feature +++ /dev/null @@ -1,14 +0,0 @@ -# language: en -@cloudwatch -Feature: Amazon CloudWatch - - I want to use Amazon CloudWatch - - Scenario: Alarms - Given I create a CloudWatch alarm with prefix "aws-js-sdk-alarm" - And I list the CloudWatch alarms - Then the list should contain the CloudWatch alarm - - Scenario: Error handling - Given I create a CloudWatch alarm with prefix "" - Then the error code should be "ValidationError" diff --git a/features/cloudwatch/step_definitions/cloudwatch.js b/features/cloudwatch/step_definitions/cloudwatch.js deleted file mode 100644 index 33e6c7e83367..000000000000 --- a/features/cloudwatch/step_definitions/cloudwatch.js +++ /dev/null @@ -1,43 +0,0 @@ -const { After, Before, Given, Then } = require("@cucumber/cucumber"); - -Before({ tags: "@cloudwatch" }, function () { - const { CloudWatch } = require("../../../clients/client-cloudwatch"); - this.service = new CloudWatch({}); -}); - -After({ tags: "@cloudwatch" }, async function () { - if (this.alarmName) { - await this.service.deleteAlarms({ AlarmNames: [this.alarmName] }); - this.alarmName = undefined; - } -}); - -Given("I create a CloudWatch alarm with prefix {string}", async function (prefix) { - const alarmName = this.uniqueName(prefix); - try { - this.data = await this.service.putMetricAlarm({ - AlarmName: alarmName, - ComparisonOperator: "GreaterThanThreshold", - EvaluationPeriods: 5, - MetricName: "CPUUtilization", - Namespace: "AWS/EC2", - Period: 60, - Statistic: "Average", - Threshold: 50.0, - }); - this.alarmName = alarmName; - } catch (error) { - this.error = error; - } -}); - -Given("I list the CloudWatch alarms", async function () { - this.data = await this.service.describeAlarms({ AlarmNames: [this.alarmName] }); -}); - -Then("the list should contain the CloudWatch alarm", function () { - const name = this.alarmName; - this.assert.contains(this.data.MetricAlarms, function (alarm) { - return alarm.AlarmName === name; - }); -}); diff --git a/features/cloudwatchevents/cloudwatchevents.feature b/features/cloudwatchevents/cloudwatchevents.feature deleted file mode 100644 index d8c0f07b4c86..000000000000 --- a/features/cloudwatchevents/cloudwatchevents.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@cloudwatchevents -Feature: - - I want to use Amazon CloudWatch Events - - Scenario: Making a request - Given I run the "listRules" operation - Then the request should be successful - And the value at "Rules" should be a list - - Scenario: Error handling - Given I run the "describeRule" operation with params: - """ - { "Name": "fake_rule" } - """ - Then the error code should be "ResourceNotFoundException" diff --git a/features/cloudwatchevents/step_definitions/cloudwatchevents.js b/features/cloudwatchevents/step_definitions/cloudwatchevents.js deleted file mode 100644 index 1561cd8e18b5..000000000000 --- a/features/cloudwatchevents/step_definitions/cloudwatchevents.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@cloudwatchevents" }, function (scenario, callback) { - const { CloudWatchEvents } = require("../../../clients/client-cloudwatch-events"); - this.service = new CloudWatchEvents({}); - callback(); -}); diff --git a/features/cloudwatchlogs/cloudwatchlogs.feature b/features/cloudwatchlogs/cloudwatchlogs.feature deleted file mode 100644 index 46059bbe1a6e..000000000000 --- a/features/cloudwatchlogs/cloudwatchlogs.feature +++ /dev/null @@ -1,14 +0,0 @@ -# language: en -@cloudwatchlogs -Feature: - - I want to use Amazon CloudWatch Logs - - Scenario: Log Groups - Given I create a CloudWatch logGroup with prefix "aws-js-sdk" - And I list the CloudWatch logGroups - Then the list should contain the CloudWatch logGroup - - Scenario: Error handling - Given I create a CloudWatch logGroup with prefix "" - Then the error code should be "InvalidParameterException" diff --git a/features/cloudwatchlogs/step_definitions/cloudwatchlogs.js b/features/cloudwatchlogs/step_definitions/cloudwatchlogs.js deleted file mode 100644 index 7350cf81dbe1..000000000000 --- a/features/cloudwatchlogs/step_definitions/cloudwatchlogs.js +++ /dev/null @@ -1,30 +0,0 @@ -const { Before, Given, Then, After } = require("@cucumber/cucumber"); - -Before({ tags: "@cloudwatchlogs" }, function () { - const { CloudWatchLogs } = require("../../../clients/client-cloudwatch-logs"); - this.service = new CloudWatchLogs({}); -}); - -After({ tags: "@cloudwatchlogs" }, async function () { - if (this.logGroupName) { - await this.service.deleteLogGroup({ logGroupName: this.logGroupName }); - } -}); - -Given("I create a CloudWatch logGroup with prefix {string}", function (prefix, callback) { - const expectErr = prefix === "" ? false : undefined; - this.logGroupName = this.uniqueName(prefix); - this.request(null, "createLogGroup", { logGroupName: this.logGroupName }, callback, expectErr); -}); - -Given("I list the CloudWatch logGroups", function (callback) { - this.request(null, "describeLogGroups", { logGroupNamePrefix: this.logGroupName }, callback); -}); - -Then("the list should contain the CloudWatch logGroup", function (callback) { - const name = this.logGroupName; - this.assert.contains(this.data.logGroups, function (alarm) { - return alarm.logGroupName === name; - }); - callback(); -}); diff --git a/features/codecommit/codecommit.feature b/features/codecommit/codecommit.feature deleted file mode 100644 index a8dc69d2504a..000000000000 --- a/features/codecommit/codecommit.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@codecommit -Feature: AWS CodeCommit - - I want to use AWS CodeCommit - - Scenario: Listing repositories - Given I run the "listRepositories" operation - Then the request should be successful - And the value at "repositories" should be a list - - Scenario: Error handling - Given I run the "listBranches" operation with params: - """ - { "repositoryName": "fake-repo" } - """ - Then the error code should be "RepositoryDoesNotExistException" diff --git a/features/codecommit/step_definitions/codecommit.js b/features/codecommit/step_definitions/codecommit.js deleted file mode 100644 index 1e24b6571510..000000000000 --- a/features/codecommit/step_definitions/codecommit.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@codecommit" }, function (scenario, callback) { - const { CodeCommit } = require("../../../clients/client-codecommit"); - this.service = new CodeCommit({ region: "us-east-1" }); - callback(); -}); diff --git a/features/codedeploy/codedeploy.feature b/features/codedeploy/codedeploy.feature deleted file mode 100644 index 4bdf0a5cd675..000000000000 --- a/features/codedeploy/codedeploy.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@codedeploy -Feature: AWS CodeDeploy - - I want to use AWS CodeDeploy - - Scenario: Listing Applicaitons - Given I run the "listApplications" operation - Then the request should be successful - And the value at "applications" should be a list - - Scenario: Error handling - Given I run the "createApplication" operation with params: - """ - { "applicationName": "" } - """ - Then the error code should be "ApplicationNameRequiredException" diff --git a/features/codedeploy/step_definitions/codedeploy.js b/features/codedeploy/step_definitions/codedeploy.js deleted file mode 100644 index 8cf138be2a0a..000000000000 --- a/features/codedeploy/step_definitions/codedeploy.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@codedeploy" }, function (scenario, callback) { - const { CodeDeploy } = require("../../../clients/client-codedeploy"); - this.service = new CodeDeploy({}); - callback(); -}); diff --git a/features/codepipeline/codepipeline.feature b/features/codepipeline/codepipeline.feature deleted file mode 100644 index d8e9bb8fb123..000000000000 --- a/features/codepipeline/codepipeline.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@codepipeline -Feature: AWS CodePipeline - - I want to use AWS CodePipeline - - Scenario: Listing repositories - Given I run the "listPipelines" operation - Then the request should be successful - And the value at "pipelines" should be a list - - Scenario: Error handling - Given I run the "getPipeline" operation with params: - """ - { "name": "fake-pipeline" } - """ - Then the error code should be "PipelineNotFoundException" diff --git a/features/codepipeline/step_definitions/codepipeline.js b/features/codepipeline/step_definitions/codepipeline.js deleted file mode 100644 index 04b65a2cbe7a..000000000000 --- a/features/codepipeline/step_definitions/codepipeline.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@codepipeline" }, function (scenario, callback) { - const { CodePipeline } = require("../../../clients/client-codepipeline"); - this.service = new CodePipeline({ region: "us-east-1" }); - callback(); -}); diff --git a/features/cognitoidentity/cognitoidentity.feature b/features/cognitoidentity/cognitoidentity.feature deleted file mode 100644 index 9e78fa78f949..000000000000 --- a/features/cognitoidentity/cognitoidentity.feature +++ /dev/null @@ -1,14 +0,0 @@ -# language: en -@cognitoidentity -Feature: - - I want to use Amazon Cognito Identity - - Scenario: Identity Pools - Given I create a Cognito identity pool with prefix "awssdkjs" - And I describe the Cognito identity pool ID - Then the status code should be 200 - - Scenario: Error handling - Given I create a Cognito identity pool with prefix "" - Then the error code should be "ValidationException" diff --git a/features/cognitoidentity/step_definitions/cognitoidentity.js b/features/cognitoidentity/step_definitions/cognitoidentity.js deleted file mode 100644 index 72ab7f706c76..000000000000 --- a/features/cognitoidentity/step_definitions/cognitoidentity.js +++ /dev/null @@ -1,29 +0,0 @@ -const { After, Before, Given } = require("@cucumber/cucumber"); - -Before({ tags: "@cognitoidentity" }, function () { - const { CognitoIdentity } = require("../../../clients/client-cognito-identity"); - this.service = new CognitoIdentity({}); -}); - -After({ tags: "@cognitoidentity" }, async function () { - if (this.identityPoolId) { - this.service.deleteIdentityPool({ IdentityPoolId: this.identityPoolId }); - this.identityPoolId = undefined; - } -}); - -Given("I create a Cognito identity pool with prefix {string}", async function (prefix) { - try { - this.data = await this.service.createIdentityPool({ - IdentityPoolName: this.uniqueName(prefix), - AllowUnauthenticatedIdentities: true, - }); - this.identityPoolId = this.data.IdentityPoolId; - } catch (error) { - this.error = error; - } -}); - -Given("I describe the Cognito identity pool ID", async function () { - this.data = await this.service.describeIdentityPool({ IdentityPoolId: this.identityPoolId }); -}); diff --git a/features/cognitosync/cognitosync.feature b/features/cognitosync/cognitosync.feature deleted file mode 100644 index 1e93e77f35ab..000000000000 --- a/features/cognitosync/cognitosync.feature +++ /dev/null @@ -1,16 +0,0 @@ -# language: en -@cognitosync -Feature: - - I want to use Amazon Cognito Sync - - Scenario: Identity Pool Usage - Given I list Cognito identity pool usage - Then the status code should be 200 - - Scenario: Error handling - Given I list Cognito data sets with identity pool id "INVALID" and identity id "A:B:C" - Then the error message should contain: - """ - validation errors detected - """ diff --git a/features/cognitosync/step_definitions/cognitosync.js b/features/cognitosync/step_definitions/cognitosync.js deleted file mode 100644 index fbe35278f5a4..000000000000 --- a/features/cognitosync/step_definitions/cognitosync.js +++ /dev/null @@ -1,19 +0,0 @@ -const { Before, Given } = require("@cucumber/cucumber"); - -Before({ tags: "@cognitosync" }, function (scenario, callback) { - const { CognitoSync } = require("../../../clients/client-cognito-sync"); - this.service = new CognitoSync({}); - callback(); -}); - -Given("I list Cognito identity pool usage", function (callback) { - this.request(null, "listIdentityPoolUsage", {}, callback); -}); - -Given( - "I list Cognito data sets with identity pool id {string} and identity id {string}", - function (idpid, idid, callback) { - const params = { IdentityPoolId: idpid, IdentityId: idid }; - this.request(null, "listDatasets", params, callback, false); - } -); diff --git a/features/configservice/configservice.feature b/features/configservice/configservice.feature deleted file mode 100644 index fcfe2c0b40ae..000000000000 --- a/features/configservice/configservice.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@configservice -Feature: AWS Config - - I want to use AWS Config - - Scenario: Listing delivery channels - Given I run the "describeDeliveryChannels" operation - Then the request should be successful - And the value at "DeliveryChannels" should be a list - - Scenario: Error handling - Given I run the "putDeliveryChannel" operation with params: - """ - { "DeliveryChannel": { "name": "" } } - """ - Then the error code should be "ValidationException" diff --git a/features/configservice/step_definitions/configservice.js b/features/configservice/step_definitions/configservice.js deleted file mode 100644 index 4e105dd37ce2..000000000000 --- a/features/configservice/step_definitions/configservice.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@configservice" }, function (scenario, callback) { - const { ConfigService } = require("../../../clients/client-config-service"); - this.service = new ConfigService({}); - callback(); -}); diff --git a/features/datapipeline/datapipeline.feature b/features/datapipeline/datapipeline.feature deleted file mode 100644 index 1069f468bfdf..000000000000 --- a/features/datapipeline/datapipeline.feature +++ /dev/null @@ -1,18 +0,0 @@ -# language: en -@datapipeline -Feature: AWS Data Pipeline - - I want to use AWS Data Pipeline - - Scenario: Listing pipelines - Given I run the "listPipelines" operation - Then the request should be successful - And the value at "pipelineIdList" should be a list - - Scenario: Error handling - Given I create a Data Pipeline with name prefix "" - Then the error code should be "ValidationException" - And the error message should match: - """ - Member must have length greater than or equal to 1 - """ diff --git a/features/datapipeline/step_definitions/datapipeline.js b/features/datapipeline/step_definitions/datapipeline.js deleted file mode 100644 index 562b79ee5017..000000000000 --- a/features/datapipeline/step_definitions/datapipeline.js +++ /dev/null @@ -1,15 +0,0 @@ -const { Before, Given } = require("@cucumber/cucumber"); - -Before({ tags: "@datapipeline" }, function (scenario, callback) { - const { DataPipeline } = require("../../../clients/client-data-pipeline"); - this.service = new DataPipeline({}); - callback(); -}); - -Given("I create a Data Pipeline with name prefix {string}", function (prefix, callback) { - const params = { - name: this.uniqueName(prefix), - uniqueId: this.uniqueName("aws-js-sdk"), - }; - this.request(null, "createPipeline", params, callback, false); -}); diff --git a/features/devicefarm/devicefarm.feature b/features/devicefarm/devicefarm.feature deleted file mode 100644 index 666f164a2160..000000000000 --- a/features/devicefarm/devicefarm.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@devicefarm -Feature: AWS Device Farm - - I want to use AWS Device Farm - - Scenario: Listing devices - Given I run the "listDevices" operation - Then the request should be successful - And the value at "devices" should be a list - - Scenario: Error handling - Given I run the "getDevice" operation with params: - """ - { "arn": "arn:aws:devicefarm:us-west-2::device:00000000000000000000000000000000" } - """ - Then the error code should be "NotFoundException" diff --git a/features/devicefarm/step_definitions/devicefarm.js b/features/devicefarm/step_definitions/devicefarm.js deleted file mode 100644 index 97499e982198..000000000000 --- a/features/devicefarm/step_definitions/devicefarm.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@devicefarm" }, function (scenario, callback) { - const { DeviceFarm } = require("../../../clients/client-device-farm"); - this.service = new DeviceFarm({ region: "us-west-2" }); - callback(); -}); diff --git a/features/directconnect/directconnect.feature b/features/directconnect/directconnect.feature deleted file mode 100644 index 57ba942cf29f..000000000000 --- a/features/directconnect/directconnect.feature +++ /dev/null @@ -1,14 +0,0 @@ -# language: en -@directconnect -Feature: AWS Direct Connect - - I want to use AWS Direct Connect - - Scenario: describe connections - Given I run the "describeConnections" operation - Then the request should be successful - And the value at "connections" should be a list - - Scenario: Error handling - Given I create a Direct Connect connection with an invalid location - Then the error code should be "DirectConnectClientException" diff --git a/features/directconnect/step_definitions/directconnect.js b/features/directconnect/step_definitions/directconnect.js deleted file mode 100644 index 28b55235de91..000000000000 --- a/features/directconnect/step_definitions/directconnect.js +++ /dev/null @@ -1,16 +0,0 @@ -const { Before, Given } = require("@cucumber/cucumber"); - -Before({ tags: "@directconnect" }, function (scenario, callback) { - const { DirectConnect } = require("../../../clients/client-direct-connect"); - this.service = new DirectConnect({}); - callback(); -}); - -Given("I create a Direct Connect connection with an invalid location", function (callback) { - const params = { - bandwidth: "1Gbps", - location: "INVALID_LOCATION", - connectionName: this.uniqueName("aws-sdk-js"), - }; - this.request(null, "createConnection", params, callback, false); -}); diff --git a/features/directoryservice/directoryservice.feature b/features/directoryservice/directoryservice.feature deleted file mode 100644 index eeca7c887f2d..000000000000 --- a/features/directoryservice/directoryservice.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@directoryservice -Feature: AWS Directory Service - - I want to use AWS Directory Service - - Scenario: Listing directories - Given I run the "describeDirectories" operation - Then the request should be successful - And the value at "DirectoryDescriptions" should be a list - - Scenario: Error handling - Given I run the "createDirectory" operation with params: - """ - { "Name": "", "Password": "" , "Size": ""} - """ - Then the error code should be "ValidationException" diff --git a/features/directoryservice/step_definitions/directoryservice.js b/features/directoryservice/step_definitions/directoryservice.js deleted file mode 100644 index 331e74f6156e..000000000000 --- a/features/directoryservice/step_definitions/directoryservice.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@directoryservice" }, function (scenario, callback) { - const { DirectoryService } = require("../../../clients/client-directory-service"); - this.service = new DirectoryService({}); - callback(); -}); diff --git a/features/dms/dms.feature b/features/dms/dms.feature deleted file mode 100644 index ad577d55b6dc..000000000000 --- a/features/dms/dms.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@databasemigrationservice -Feature: - - I want to use AWS Database Migration Service - - Scenario: Making a request - Given I run the "describeEndpoints" operation - Then the request should be successful - And the value at "Endpoints" should be a list - - Scenario: Error handling - Given I run the "startReplicationTask" operation with params: - """ - { "ReplicationTaskArn": "fake-arn", "StartReplicationTaskType": "fake-arn"} - """ - Then the error code should be "InvalidParameterValueException" diff --git a/features/dms/step_definitions/dms.js b/features/dms/step_definitions/dms.js deleted file mode 100644 index a93885a99992..000000000000 --- a/features/dms/step_definitions/dms.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@databasemigrationservice" }, function (scenario, callback) { - const { DatabaseMigrationService } = require("../../../clients/client-database-migration-service"); - this.service = new DatabaseMigrationService({}); - callback(); -}); diff --git a/features/dynamodb/step_definitions/dynamodb.js b/features/dynamodb/step_definitions/dynamodb.js deleted file mode 100644 index 22b615c57176..000000000000 --- a/features/dynamodb/step_definitions/dynamodb.js +++ /dev/null @@ -1,143 +0,0 @@ -const { AfterAll, Before, Given, Then, When } = require("@cucumber/cucumber"); -const { DynamoDB } = require("../../../clients/client-dynamodb"); -const jmespath = require("jmespath"); - -let tableName; - -Before({ tags: "@dynamodb" }, function () { - this.service = new DynamoDB({ maxRetries: 2 }); -}); - -AfterAll({ tags: "@dynamodb" }, async function () { - if (tableName) { - const client = new DynamoDB({ maxRetries: 2 }); - await client.deleteTable({ TableName: tableName }); - tableName = undefined; - } -}); - -Given("I have a table", async function () { - await this.service.describeTable({ TableName: this.tableName }); -}); - -When("I create a table", async function () { - tableName = this.uniqueName("aws-sdk-js-integration"); - const params = { - TableName: tableName, - AttributeDefinitions: [{ AttributeName: "id", AttributeType: "S" }], - KeySchema: [{ AttributeName: "id", KeyType: "HASH" }], - BillingMode: "PAY_PER_REQUEST", - }; - this.tableName = tableName; - await this.service.createTable(params); -}); - -When("I put the item:", async function (string) { - const params = { TableName: this.tableName, Item: JSON.parse(string) }; - await this.service.putItem(params); -}); - -When("I put a recursive item", async function () { - const params = { - TableName: this.tableName, - Item: { - id: { S: "fooRecursive" }, - data: { - M: { - attr1: { - L: [{ S: "value1" }, { L: [{ M: { attr12: { S: "value2" } } }] }], - }, - attr2: { - L: [{ B: new Uint8Array([0]) }, { B: new Uint8Array([1]) }, { NULL: true }, { BOOL: true }], - }, - }, - }, - }, - }; - this.data = await this.service.putItem(params); -}); - -Then("the item with id {string} should exist", async function (key) { - const params = { TableName: this.tableName, Key: { id: { S: key } } }; - this.data = await this.service.getItem(params); -}); - -Then("it should have attribute {string} containing {string}", async function (attr, value) { - this.assert.equal(jmespath.search(this.data.Item, attr), value); -}); - -Then("the table should eventually exist", async function () { - const { waitUntilTableExists } = require("../../../clients/client-dynamodb"); - await waitUntilTableExists({ client: this.service }, { TableName: this.tableName }); -}); - -Given("my first request is corrupted with CRC checking (ON|OFF)", function (toggle, callback) { - const world = this; - this.service.config.dynamoDbCrc32 = toggle == "ON" ? true : false; - const req = this.service.listTables(); - this.service.config.dynamoDbCrc32 = true; - req.removeAllListeners("httpData"); - req.on("httpData", function (chunk, resp) { - if (resp.retryCount == 0) { - resp.httpResponse.body = Buffer.from('{"invalid":"response"}'); - } else { - world.AWS.EventListeners.Core.HTTP_DATA.call(this, chunk, resp); - } - }); - req.on("complete", function (resp) { - world.error = resp.error; - world.response = resp; - if (resp.error) callback(resp.error); - else callback(); - }); - req.send(); -}); - -Then("the request should( not)? be retried", function (retry, callback) { - if (retry && this.data.$metadata.retries > 0) callback(new Error("Request was incorrectly retried")); - if (!retry && this.data.$metadata.retries == 0) callback(new Error("Request was incorrectly retried")); - callback(); -}); - -Given("all of my requests are corrupted with CRC checking ON", function (callback) { - const world = this; - const req = this.service.listTables(); - req.removeAllListeners("httpData"); - req.on("httpData", function (chunk, resp) { - resp.httpResponse.body = Buffer.from('{"invalid":"response"}'); - }); - req.on("complete", function (resp) { - world.error = resp.error; - world.response = resp; - callback(); - }); - req.send(); -}); - -When("the request is retried the maximum number of times", function (callback) { - if (this.data.$metadata.retries != 2) callback(new Error("Incorrect retry count")); - callback(); -}); - -Then("the request should( not)? fail with a CRC checking error", function (failed, callback) { - if (failed && this.error) callback(this.error); - if (!failed && !this.error) callback(new Error("Did not fail when should have")); - callback(); -}); - -Given("I try to delete an item with key {string} from table {string}", async function (key, table) { - const params = { TableName: table, Key: { id: { S: key } } }; - try { - this.data = await this.service.deleteItem(params); - } catch (error) { - this.error = error; - } -}); - -Given("I try to delete a table with an empty table parameter", async function () { - try { - this.data = await this.service.deleteTable({ TableName: "" }); - } catch (error) { - this.error = error; - } -}); diff --git a/features/dynamodb/tables.feature b/features/dynamodb/tables.feature deleted file mode 100644 index 540a5f4fd16f..000000000000 --- a/features/dynamodb/tables.feature +++ /dev/null @@ -1,48 +0,0 @@ -# language: en - -@dynamodb @tables -Feature: DynamoDB Tables - - Scenario: Creating a table - When I create a table - Then the table should eventually exist - - Scenario: Item CRUD - Given I have a table - When I put the item: - """ - {"id": {"S": "foo"}, "data": {"S": "bår"}} - """ - Then the item with id "foo" should exist - And it should have attribute "data.S" containing "bår" - - Scenario: UTF-8 support - Given I try to delete an item with key "føø" from table "table" - Then the error code should be "ResourceNotFoundException" - - Scenario: Improper table deletion - Given I try to delete a table with an empty table parameter - Then the error code should be "ValidationException" - And the error status code should be 400 - - @recursive - Scenario: Recursive Attributes - Given I have a table - When I put a recursive item - Then the item with id "fooRecursive" should exist - And it should have attribute "data.M.attr1.L[1].L[0].M.attr12.S" containing "value2" - -# @dynamodb @crc32 -# Feature: CRC32 response validation -# Scenario: Retry on corrupted request -# Given my first request is corrupted with CRC checking ON -# Then the request should be retried -# And the request should not fail with a CRC checking error -# Scenario: Failed retries on corrupted request -# Given all of my requests are corrupted with CRC checking ON -# Then the request is retried the maximum number of times -# And the request should fail with a CRC checking error -# Scenario: Ignore corrupted request with CRC checking OFF -# Given my first request is corrupted with CRC checking OFF -# Then the request should not be retried -# And the request should not fail with a CRC checking error \ No newline at end of file diff --git a/features/dynamodbstreams/dynamodbstreams.feature b/features/dynamodbstreams/dynamodbstreams.feature deleted file mode 100644 index 2d09eafd68a5..000000000000 --- a/features/dynamodbstreams/dynamodbstreams.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@dynamodbstreams -Feature: Amazon DynamoDB Streams - - I want to use Amazon DynamoDB Streams - - Scenario: Listing streams - Given I run the "listStreams" operation - Then the request should be successful - And the value at "Streams" should be a list - - Scenario: Error handling - Given I run the "describeStream" operation with params: - """ - { "StreamArn": "fake-stream" } - """ - Then the error code should be "ValidationException" diff --git a/features/dynamodbstreams/step_definitions/dynamodbstreams.js b/features/dynamodbstreams/step_definitions/dynamodbstreams.js deleted file mode 100644 index 2ef9ee631378..000000000000 --- a/features/dynamodbstreams/step_definitions/dynamodbstreams.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@dynamodbstreams" }, function (scenario, callback) { - const { DynamoDBStreams } = require("../../../clients/client-dynamodb-streams"); - this.service = new DynamoDBStreams({}); - callback(); -}); diff --git a/features/ecr/ecr.feature b/features/ecr/ecr.feature deleted file mode 100644 index 077fc4efa2c2..000000000000 --- a/features/ecr/ecr.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@ecr -Feature: - - I want to use Amazon EC2 Container Registry - - Scenario: Making a request - Given I run the "describeRepositories" operation - Then the request should be successful - And the value at "repositories" should be a list - - Scenario: Error handling - Given I run the "listImages" operation with params: - """ - { "repositoryName": "fake_name" } - """ - Then the error code should be "RepositoryNotFoundException" diff --git a/features/ecr/step_definitions/ecr.js b/features/ecr/step_definitions/ecr.js deleted file mode 100644 index 9e41b8037f64..000000000000 --- a/features/ecr/step_definitions/ecr.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@ecr" }, function (scenario, callback) { - const { ECR } = require("../../../clients/client-ecr"); - this.service = new ECR({}); - callback(); -}); diff --git a/features/ecs/ecs.feature b/features/ecs/ecs.feature deleted file mode 100644 index 4fb454283bf4..000000000000 --- a/features/ecs/ecs.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@ecs -Feature: Amazon ECS - - I want to use Amazon ECS - - Scenario: Listing clusters - Given I run the "listClusters" operation - Then the request should be successful - And the value at "clusterArns" should be a list - - Scenario: Error handling - Given I run the "stopTask" operation with params: - """ - { "task": "xxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxx" } - """ - Then the error status code should be 400 diff --git a/features/ecs/step_definitions/ecs.js b/features/ecs/step_definitions/ecs.js deleted file mode 100644 index c85b9f11c9e5..000000000000 --- a/features/ecs/step_definitions/ecs.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@ecs" }, function (scenario, callback) { - const { ECS } = require("../../../clients/client-ecs"); - this.service = new ECS({}); - callback(); -}); diff --git a/features/efs/efs.feature b/features/efs/efs.feature deleted file mode 100644 index 9d9ade60ec07..000000000000 --- a/features/efs/efs.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@efs -Feature: Amazon Elastic File System - - I want to use Amazon Elastic File System - - Scenario: Listing file systems - Given I run the "describeFileSystems" operation - Then the request should be successful - And the value at "FileSystems" should be a list - - Scenario: Error handling - Given I run the "deleteFileSystem" operation with params: - """ - { "FileSystemId": "fake-id" } - """ - Then the error code should be "ValidationException" diff --git a/features/efs/step_definitions/efs.js b/features/efs/step_definitions/efs.js deleted file mode 100644 index 840a3b86ffb9..000000000000 --- a/features/efs/step_definitions/efs.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@efs" }, function (scenario, callback) { - const { EFS } = require("../../../clients/client-efs"); - this.service = new EFS({ region: "us-west-2" }); - callback(); -}); diff --git a/features/elasticache/elasticache.feature b/features/elasticache/elasticache.feature deleted file mode 100644 index 5eb890c2a685..000000000000 --- a/features/elasticache/elasticache.feature +++ /dev/null @@ -1,20 +0,0 @@ -# language: en -@elasticache -Feature: Amazon ElastiCache - - I want to use Amazon ElastiCache - - Scenario: Creating and deleting cache parameter groups - Given I create a cache parameter group with name prefix "aws-js-sdk" - And the cache parameter group name is in the result - And I describe the cache parameter groups - Then the value at "CacheParameterGroups" should be a list - And the cache parameter group should be described - - Scenario: Error handling - Given I create a cache parameter group with name prefix "" - Then the error code should be "InvalidParameterValueException" - Then the error message should contain: - """ - The parameter CacheParameterGroupName must be provided and must not be blank - """ diff --git a/features/elasticache/step_definitions/elasticache.js b/features/elasticache/step_definitions/elasticache.js deleted file mode 100644 index bb0b7eef9b59..000000000000 --- a/features/elasticache/step_definitions/elasticache.js +++ /dev/null @@ -1,46 +0,0 @@ -const { After, Before, Given, Then } = require("@cucumber/cucumber"); - -Before({ tags: "@elasticache" }, function () { - const { ElastiCache } = require("../../../clients/client-elasticache"); - this.service = new ElastiCache({}); -}); - -After({ tags: "@elasticache" }, async function () { - if (this.cacheGroupName) { - await this.service.deleteCacheParameterGroup({ CacheParameterGroupName: this.cacheGroupName }); - this.cacheGroupName = undefined; - } -}); - -Given("I create a cache parameter group with name prefix {string}", async function (prefix) { - this.cacheGroupName = this.uniqueName(prefix); - const params = { - Description: "Description", - CacheParameterGroupName: this.cacheGroupName, - CacheParameterGroupFamily: "memcached1.4", - }; - try { - this.data = await this.service.createCacheParameterGroup(params); - } catch (error) { - this.error = error; - } -}); - -Given("the cache parameter group name is in the result", async function () { - const name = this.data.CacheParameterGroup.CacheParameterGroupName; - this.assert.equal(name, this.cacheGroupName); -}); - -Given("I describe the cache parameter groups", async function () { - const params = { CacheParameterGroupName: this.cacheGroupName }; - try { - this.data = await this.service.describeCacheParameterGroups(params); - } catch (error) { - this.error = error; - } -}); - -Then("the cache parameter group should be described", function () { - const item = this.data.CacheParameterGroups[0]; - this.assert.equal(item.CacheParameterGroupName, this.cacheGroupName); -}); diff --git a/features/elasticbeanstalk/elasticbeanstalk.feature b/features/elasticbeanstalk/elasticbeanstalk.feature deleted file mode 100644 index 8fba7346e9c7..000000000000 --- a/features/elasticbeanstalk/elasticbeanstalk.feature +++ /dev/null @@ -1,21 +0,0 @@ -# language: en -@elasticbeanstalk -Feature: AWS Elastic Beanstalk - - I want to use AWS Elastic Beanstalk - - @requiresakid - Scenario: Creating applications and application versions - Given I create an Elastic Beanstalk application with name prefix "aws-js-sdk" - And I create an Elastic Beanstalk application version with label "1.0.0" - And I describe the Elastic Beanstalk application - Then the result should contain the Elastic Beanstalk application version - And the result should contain the Elastic Beanstalk application name - - Scenario: Error handling - Given I create an Elastic Beanstalk application with name prefix "" - Then the error code should be "ValidationError" - And the error message should match: - """ - Value '' at 'applicationName' - """ diff --git a/features/elasticbeanstalk/step_definitions/elasticbeanstalk.js b/features/elasticbeanstalk/step_definitions/elasticbeanstalk.js deleted file mode 100644 index a8eafce5a4bf..000000000000 --- a/features/elasticbeanstalk/step_definitions/elasticbeanstalk.js +++ /dev/null @@ -1,44 +0,0 @@ -const { After, Before, Given, Then } = require("@cucumber/cucumber"); - -Before({ tags: "@elasticbeanstalk" }, function () { - const { ElasticBeanstalk } = require("../../../clients/client-elastic-beanstalk"); - this.service = new ElasticBeanstalk({}); -}); - -After({ tags: "@elasticbeanstalk" }, async function () { - if (this.appName) { - await this.service.deleteApplication({ ApplicationName: this.appName }); - this.appName = undefined; - } -}); - -Given("I create an Elastic Beanstalk application with name prefix {string}", async function (prefix) { - this.appName = this.uniqueName(prefix); - try { - this.data = await this.service.createApplication({ ApplicationName: this.appName }); - } catch (error) { - this.error = error; - } -}); - -Given("I create an Elastic Beanstalk application version with label {string}", async function (label) { - this.appVersion = label; - const params = { - ApplicationName: this.appName, - VersionLabel: this.appVersion, - }; - await this.service.createApplicationVersion(params); -}); - -Given("I describe the Elastic Beanstalk application", async function () { - const params = { ApplicationNames: [this.appName] }; - this.data = await this.service.describeApplications(params); -}); - -Then("the result should contain the Elastic Beanstalk application version", function () { - this.assert.deepEqual(this.data.Applications[0].Versions, [this.appVersion]); -}); - -Then("the result should contain the Elastic Beanstalk application name", function () { - this.assert.equal(this.data.Applications[0].ApplicationName, this.appName); -}); diff --git a/features/elb/elb.feature b/features/elb/elb.feature deleted file mode 100644 index 8352633df9e8..000000000000 --- a/features/elb/elb.feature +++ /dev/null @@ -1,14 +0,0 @@ -# language: en -@elasticloadbalancing -Feature: Elastic Load Balancing - - I want to use Elastic Load Balancing - - Scenario: Making a request - Given I run the "describeLoadBalancers" operation - Then the request should be successful - - Scenario: Error handling - Given I create a load balancer with name prefix "verylongelasticloadbalancername" - Then the error code should be "ValidationError" - And the error status code should be 400 diff --git a/features/elb/step_definitions/elb.js b/features/elb/step_definitions/elb.js deleted file mode 100644 index ca93252a0e21..000000000000 --- a/features/elb/step_definitions/elb.js +++ /dev/null @@ -1,48 +0,0 @@ -const { Before, Given, Then } = require("@cucumber/cucumber"); - -Before({ tags: "@elasticloadbalancing" }, function (scenario, callback) { - const { ElasticLoadBalancing } = require("../../../clients/client-elastic-load-balancing"); - this.service = new ElasticLoadBalancing({}); - callback(); -}); - -Given("I create a load balancer with name prefix {string}", function (prefix, callback) { - this.loadBalancerName = prefix + "-" + new Date().getTime(); - - const params = { - LoadBalancerName: this.loadBalancerName, - Listeners: [ - { - Protocol: "TCP", - LoadBalancerPort: 80, - InstancePort: 80, - }, - ], - AvailabilityZones: ["us-east-1a"], - }; - this.request(null, "createLoadBalancer", params, callback, false); -}); - -Given("I describe load balancers with the load balancer name", function (callback) { - const params = { - LoadBalancerNames: [this.loadBalancerName], - }; - this.request(null, "describeLoadBalancers", params, callback); -}); - -Then("the load balancer should be in the list", function (callback) { - const name = this.data.LoadBalancerDescriptions[0].LoadBalancerName; - this.assert.equal(name, this.loadBalancerName); - callback(); -}); - -Then("I delete the load balancer", function (callback) { - const params = { - LoadBalancerName: this.loadBalancerName, - }; - this.request(null, "deleteLoadBalancer", params, callback); -}); - -Given("I try to create a load balancer with no name", function (callback) { - this.request(null, "createLoadBalancer", {}, callback); -}); diff --git a/features/elbv2/elbv2.feature b/features/elbv2/elbv2.feature deleted file mode 100644 index d1c5a41dc57b..000000000000 --- a/features/elbv2/elbv2.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@elasticloadbalancingv2 -Feature: - - I want to use Elastic Load Balancing v2 - - Scenario: Making a request - Given I run the "describeTargetGroups" operation - Then the request should be successful - And the value at "TargetGroups" should be a list - - Scenario: Error handling - Given I run the "describeTags" operation with params: - """ - { "ResourceArns": ["fake_arn"] } - """ - Then the error code should be "ValidationError" diff --git a/features/elbv2/step_definitions/elbv2.js b/features/elbv2/step_definitions/elbv2.js deleted file mode 100644 index 589a0dde73dc..000000000000 --- a/features/elbv2/step_definitions/elbv2.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@elasticloadbalancingv2" }, function (scenario, callback) { - const { ElasticLoadBalancingV2 } = require("../../../clients/client-elastic-load-balancing-v2"); - this.service = new ElasticLoadBalancingV2({}); - callback(); -}); diff --git a/features/emr/emr.feature b/features/emr/emr.feature deleted file mode 100644 index c5ccaa0c081f..000000000000 --- a/features/emr/emr.feature +++ /dev/null @@ -1,14 +0,0 @@ -# language: en -@emr -Feature: Amazon Elastic MapReduce - - I want to use Amazon Elastic MapReduce - - Scenario: Making a request - Given I run the "listClusters" operation - Then the request should be successful - And the value at "Clusters" should be a list - - Scenario: Error handling - Given I run an EMR job flow with invalid parameters - Then the error code should be "ValidationException" diff --git a/features/emr/step_definitions/emr.js b/features/emr/step_definitions/emr.js deleted file mode 100644 index 8471fe622563..000000000000 --- a/features/emr/step_definitions/emr.js +++ /dev/null @@ -1,14 +0,0 @@ -const { Before, Given } = require("@cucumber/cucumber"); - -Before({ tags: "@emr" }, function (scenario, callback) { - const { EMR } = require("../../../clients/client-emr"); - this.EMR = EMR; - this.service = new EMR({}); - callback(); -}); - -Given("I run an EMR job flow with invalid parameters", function (callback) { - this.service = new this.EMR({}); - const params = { Name: "", Instances: { MasterInstanceType: "invalid" } }; - this.request(null, "runJobFlow", params, callback, false); -}); diff --git a/features/es/es.feature b/features/es/es.feature deleted file mode 100644 index cf5682158332..000000000000 --- a/features/es/es.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@elasticsearchservice -Feature: - - I want to use Amazon ES - - Scenario: Making a request - Given I run the "listDomainNames" operation - Then the request should be successful - And the value at "DomainNames" should be a list - - Scenario: Error handling - Given I run the "describeElasticsearchDomain" operation with params: - """ - { "DomainName": "not-a-domain" } - """ - Then the error code should be "ResourceNotFoundException" diff --git a/features/es/step_definitions/es.js b/features/es/step_definitions/es.js deleted file mode 100644 index 9365a53ba64a..000000000000 --- a/features/es/step_definitions/es.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@elasticsearchservice" }, function (scenario, callback) { - const { ElasticsearchService } = require("../../../clients/client-elasticsearch-service"); - this.service = new ElasticsearchService({}); - callback(); -}); diff --git a/features/extra/assertions.js b/features/extra/assertions.js deleted file mode 100644 index cb7740c26d60..000000000000 --- a/features/extra/assertions.js +++ /dev/null @@ -1,28 +0,0 @@ -const assert = require("assert"); - -assert.match = function assertMatches(string, matcher, message) { - assert.ok(string.match(matcher), message || "Expected " + string + " to match " + matcher); -}; - -assert.contains = function assertContains(list, matcher, message) { - let found = false; - for (const itemIndex in list) { - if (!list.hasOwnProperty(itemIndex)) continue; - if (typeof matcher === "function") { - found = matcher(list[itemIndex]); - } else { - found = list[itemIndex] === matcher; - } - if (found) return; - } - assert.fail(list, matcher, message, "does not contain"); -}; - -assert.compare = function assertComparison(actual, operator, expected, message) { - const compare = actual + " " + operator + " " + expected; - assert.ok(eval(compare), message || compare); -}; - -module.exports = { - assert: assert, -}; diff --git a/features/extra/cleanup.js b/features/extra/cleanup.js deleted file mode 100644 index 3f0f35780609..000000000000 --- a/features/extra/cleanup.js +++ /dev/null @@ -1,83 +0,0 @@ -const { S3 } = require("../../clients/client-s3"); -const { AfterAll } = require("@cucumber/cucumber"); - -/** - * Cleanup fixtures and resources. The world does not exist when - * this handler is executed. Only resource cleanup and shutdown - * should happen here. - */ -AfterAll(async () => { - const path = require("path"); - const fs = require("fs"); - const filePath = path.resolve("e2e.buckets.json"); - - try { - if (!fs.existsSync(filePath)) return Promise.resolve(); - deleteFixtures(); - const cache = JSON.parse(fs.readFileSync(filePath)); - const buckets = cache.buckets; - if (buckets.length) { - for (let i = 0; i < buckets.length; i++) { - await cleanBucket(buckets[i]); - } - } else { - return Promise.resolve(); - } - } catch (fileErr) { - return Promise.reject(fileErr); - } finally { - if (fs.existsSync(filePath)) { - fs.unlinkSync(filePath); - } - } -}); - -/** - * Delete fixtures - */ -const deleteFixtures = function () { - const fs = require("fs"); - const path = require("path"); - const fixturePath = path.resolve("./features/extra/fixtures/tmp"); - if (fs.existsSync(fixturePath)) { - fs.readdirSync(fixturePath).forEach(function (file) { - fs.unlinkSync(path.join(fixturePath, file)); - }); - fs.rmdirSync(fixturePath); - } -}; - -/* - * Delete objects and then bucket. - */ -const cleanBucket = async (bucket) => { - await deleteObjects(bucket); - await deleteBucket(bucket); -}; - -/* - * Delete bucket - */ -const deleteBucket = async (bucket) => { - const s3 = new S3({ maxRetries: 100 }); - return s3.deleteBucket({ Bucket: bucket }); -}; - -/** - * Delete objects. - */ -const deleteObjects = async (bucket) => { - const s3 = new S3({ maxRetries: 100 }); - const params = { - Bucket: bucket, - }; - - const data = await s3.listObjects(params); - if (data.Contents && data.Contents.length > 0) { - params.Delete = { Objects: [] }; - data.Contents.forEach(function (item) { - params.Delete.Objects.push({ Key: item.Key }); - }); - await s3.deleteObjects(params); - } -}; diff --git a/features/extra/dummy.feature b/features/extra/dummy.feature deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/features/extra/fixtures/testfile.txt b/features/extra/fixtures/testfile.txt deleted file mode 100644 index d6f32e31c007..000000000000 --- a/features/extra/fixtures/testfile.txt +++ /dev/null @@ -1 +0,0 @@ -CONTENTS OF FILE diff --git a/features/extra/helpers.js b/features/extra/helpers.js deleted file mode 100644 index 62896de76dd1..000000000000 --- a/features/extra/helpers.js +++ /dev/null @@ -1,228 +0,0 @@ -const { - waitForBucketExists: bucketExists, - waitForBucketNotExists: bucketNotExists, -} = require("../../clients/client-s3"); - -module.exports = { - assert: require("./assertions").assert, - - uniqueName: function uniqueName(base, sep) { - if (sep === undefined) sep = "-"; - if (base === "") return ""; - return base + sep + new Date().getTime(); - }, - - /** - * Call this function with a block that will be executed multiple times - * to deal with eventually consistent conditions. - * - * When("I something is eventually consistent", function(callback) { - * this.eventually(callback, function(next) { - * doSomething(function(response) { - * if (response != notWhatIExpect) { - * next.fail(); - * } else { - * next(); - * } - * }); - * }); - * }); - * - * You can pass in a few options after the function: - * - * delay: The number of milliseconds to delay before retrying. - * backoff: Add this number of milliseconds to the delay between each attempt. - * maxTime: Maximum duration of milliseconds to wait for success. - */ - eventually: function eventually(callback, block, options) { - if (!options) options = {}; - if (!options.delay) options.delay = 0; - if (!options.backoff) options.backoff = 500; - if (!options.maxTime) options.maxTime = 5; - - let delay = options.delay; - const started = Date.now(); - - const self = this; - const retry = function () { - callback(); - }; - retry.fail = function (err) { - const now = Date.now(); - if (now - started < options.maxTime * 1000) { - setTimeout(function () { - delay += options.backoff; - block.call(self, retry); - }, delay); - } else { - callback(err || new Error("Eventually block timed out")); - } - }; - - block.call(this, retry); - }, - - /** - * A short-cut for calling a service operation and waiting for it to - * finish execution before moving onto the next step in the scenario. - */ - request: function request(svc, operation, params, next, extra) { - const world = this; - - if (!svc) svc = this.service; - if (typeof svc === "string") svc = this[svc]; - - svc[operation](params, function (err, data) { - world.error = err; - world.data = data; - - try { - if (next && typeof next.condition === "function") { - const condition = next.condition.call(world, world); - if (!condition) { - next.fail(new Error("Request success condition failed.")); - return; - } - } - - if (extra) { - extra.call(world, world.data); - next.call(world); - } else if (extra !== false && err) { - world.unexpectedError(svc.config.signingName, operation, world.error.name, world.error.message, next); - } else { - if (typeof next.call === "function") { - next.call(world); - } - } - } catch (err) { - if (next && typeof next.fail === "function") { - next.fail(err); - return; - } - throw err; - } - }); - }, - - /** - * Given a response that contains an error, this fails the current - * step with a formatted error message that indicates which service and - * operation failed. - */ - unexpectedError: function unexpectedError(svc, op, name, msg, next) { - var err = new Error(`Received unexpected error from ${svc}.${op}, ${name}: ${msg}`); - if (next && typeof next.fail === "function") { - next.fail(err); - return; - } - throw err; - }, - - /** - * Cache bucket names used for cleanup after all features have run. - */ - cacheBucketName: function (bucket) { - const fs = require("fs"); - const path = require("path"); - const filePath = path.resolve("e2e.buckets.json"); - let cache; - if (fs.existsSync(filePath)) { - try { - cache = JSON.parse(fs.readFileSync(filePath)); - cache.buckets.push(bucket); - fs.writeFileSync(filePath, JSON.stringify(cache)); - } catch (fileErr) { - throw fileErr; - } - } else { - cache = {}; - cache.buckets = [bucket]; - fs.writeFileSync(filePath, JSON.stringify(cache)); - } - }, - - /** - * Creates a fixture file of given size and returns the path. - */ - createFile: function (size, name) { - const fs = require("fs"); - const path = require("path"); - name = this.uniqueName(name); - // Cannot set this as a world property because the world - // is cleaned up before the AfterFeatures hook is fired. - const fixturePath = path.resolve("./features/extra/fixtures/tmp"); - if (!fs.existsSync(fixturePath)) fs.mkdirSync(fixturePath); - const filename = path.join(fixturePath, name); - let body; - if (typeof size === "string") { - switch (size) { - case "empty": - body = Buffer.alloc(0); - break; - case "small": - body = Buffer.alloc(1024 * 1024); - break; - case "large": - body = Buffer.alloc(1024 * 1024 * 20); - break; - } - } else if (typeof size === "number") { - body = Buffer.alloc(size); - } - - fs.writeFileSync(filename, body); - return filename; - }, - - /** - * Creates and returns a buffer of given size - */ - createBuffer: function (size) { - let match; - let buffer; - if ((match = size.match(/(\d+)KB/))) { - buffer = Buffer.alloc(parseInt(match[1]) * 1024); - } else if ((match = size.match(/(\d+)MB/))) { - buffer = Buffer.alloc(parseInt(match[1]) * 1024 * 1024); - } else { - switch (size) { - case "empty": - buffer = Buffer.alloc(0); - break; - case "small": - buffer = Buffer.alloc(1024 * 1024); - break; - case "large": - buffer = Buffer.alloc(1024 * 1024 * 20); - break; - default: - return Buffer.alloc(1024 * 1024); - } - } - buffer.fill("x"); - return buffer; - }, - - waitForBucketExists: function (s3client, params, callback) { - bucketExists({ client: s3client }, params).then( - function (data) { - callback(); - }, - function (err) { - callback(err); - } - ); - }, - - waitForBucketNotExists: function (s3client, params, callback) { - bucketNotExists({ client: s3client }, params).then( - function (data) { - callback(); - }, - function (err) { - callback(err); - } - ); - }, -}; diff --git a/features/extra/hooks.js b/features/extra/hooks.js deleted file mode 100644 index f819f0d88816..000000000000 --- a/features/extra/hooks.js +++ /dev/null @@ -1,202 +0,0 @@ -const util = require("util"); -const jmespath = require("jmespath"); - -const isType = (obj, type) => { - // handle cross-"frame" objects - if (typeof type === "function") type = util.typeName(type); - return Object.prototype.toString.call(obj) === "[object " + type + "]"; -}; - -const { Before, Given, Then, When, setDefaultTimeout, setWorldConstructor } = require("@cucumber/cucumber"); - -setDefaultTimeout(300 * 1000); -setWorldConstructor(require("./world.js").World); - -Before(function (scenario, callback) { - this.params = {}; - callback(); -}); - -/* Global S3 steps */ -Given("I create a shared bucket", function (callback) { - if (this.sharedBucket) return callback(); - - const bucket = (this.sharedBucket = this.uniqueName("aws-sdk-js-shared-integration")); - this.request("s3", "createBucket", { Bucket: this.sharedBucket }, function (err) { - this.cacheBucketName(this.sharedBucket); - if (err) { - callback(err); - } else { - if (err) { - return callback(err); - } - this.waitForBucketExists(this.s3, { Bucket: bucket }, callback); - } - }); -}); - -Given("I create a bucket", function (callback) { - const bucket = (this.bucket = this.uniqueName("aws-sdk-js-integration")); - this.request("s3", "createBucket", { Bucket: this.bucket }, function (err, data) { - if (err) { - return callback(err); - } - this.waitForBucketExists(this.s3, { Bucket: bucket }, callback); - }); -}); - -Then("the bucket should exist", function (next) { - this.waitForBucketExists(this.s3, { Bucket: this.bucket }, next); -}); - -Then("the bucket should not exist", function (callback) { - this.waitForBucketNotExists(this.s3, { Bucket: this.bucket }, callback); -}); - -/* Global error code steps */ - -Given("I run the {string} operation", function (operation, callback) { - this.request(null, operation, {}, callback, false); -}); - -Given("I run the {string} operation with params:", function (operation, params, callback) { - this.request(null, operation, JSON.parse(params), callback, false); -}); - -Then("the request should be successful", function (callback) { - this.assert.ok(!this.error, "Response was not successful: " + this.error); - callback(); -}); - -Then("the value at {string} should be a list", function (path, callback) { - const value = jmespath.search(this.data, path); - this.assert.ok(Array.isArray(value), "expected " + util.inspect(value) + " to be a list"); - callback(); -}); - -Then("the value at {string} should be a number", function (path, callback) { - const value = jmespath.search(this.data, path); - this.assert.ok(typeof value === "number", "expected " + util.inspect(value) + " to be a number"); - callback(); -}); - -Then("the value at {string} should be a string", function (path, callback) { - const value = jmespath.search(this.data, path); - this.assert.ok(typeof value === "string", "expected " + util.inspect(value) + " to be a string"); - callback(); -}); - -Then("the error code should be {string}", function (code, callback) { - this.assert.ok(this.error, "Response does not contain an error"); - this.assert.equal(this.error.name, code); - callback(); -}); - -Then("the error message should {word}:", function (matcher, message, callback) { - if (matcher === "be") matcher = "equal"; - if (matcher === "contain") matcher = "match"; - this.assert.ok(this.error, "Response does not contain an error"); - this.assert[matcher](this.error.message, message); - callback(); -}); - -Then("the status code should be {int}", function (status, callback) { - this.assert.equal(this.data.$metadata.httpStatusCode, parseInt(status)); - callback(); -}); - -Then("the error status code should be {int}", function (status, callback) { - this.assert.equal(this.error.$metadata.httpStatusCode, parseInt(status)); - callback(); -}); - -Then("I should get the error:", function (table, callback) { - const err = table.hashes()[0]; - this.assert.equal(this.error.name, err.name); - this.assert.equal(this.error.message, err.message); - callback(); -}); - -Given("I have a {string} service in the {string} region", function (svc, region, callback) { - this.service = new this.service.constructor({ region: region }); - callback(); -}); - -Given( - /^I paginate the "([^"]*)" operation(?: with limit (\d+))?(?: and max pages (\d+))?$/, - function (operation, limit, maxPages, callback) { - limit = parseInt(limit); - if (maxPages) maxPages = parseInt(maxPages); - - const world = this; - this.numPages = 0; - this.numMarkers = 0; - this.operation = operation; - this.paginationConfig = this.service.paginationConfig(operation); - this.params = this.params || {}; - - const marker = this.paginationConfig.outputToken; - if (this.paginationConfig.limitKey) { - this.params[this.paginationConfig.limitKey] = limit; - } - this.service[operation](this.params).eachPage(function (err, data) { - if (err) callback(err); - else if (data === null) callback(); - else if (maxPages && world.numPages === maxPages) { - callback(); - return false; - } else { - if (data[marker]) world.numMarkers++; - world.numPages++; - world.data = data; - } - }); - } -); - -Then("I should get more than one page", function (callback) { - this.assert.compare(this.numPages, ">", 1); - callback(); -}); - -Then("I should get at least one page", function (callback) { - this.assert.compare(this.numPages, ">=", 1); - callback(); -}); - -Then("I should get {int} pages", function (numPages, callback) { - this.assert.equal(this.numPages, parseInt(numPages)); - callback(); -}); - -Then("I should get numPages - 1 markers", function (callback) { - this.assert.equal(this.numMarkers, this.numPages - 1); - callback(); -}); - -Then("the last page should not contain a marker", function (callback) { - const marker = this.paginationConfig.outputToken; - this.assert.equal(this.data[marker], null); - callback(); -}); - -Then( - "the result at {word} should contain a property {word} with a(n) {word}", - function (wrapper, property, type, callback) { - if (type === "Array" || type === "Date") { - this.assert.equal(isType(this.data[wrapper][property], type), true); - } else { - this.assert.equal(typeof this.data[wrapper][property], type); - } - callback(); - } -); - -Then("the result should contain a property {word} with a(n) {word}", function (property, type, callback) { - if (type === "Array" || type === "Date") { - this.assert.equal(isType(this.data[property], type), true); - } else { - this.assert.equal(typeof this.data[property], type); - } - callback(); -}); diff --git a/features/extra/world.js b/features/extra/world.js deleted file mode 100644 index d9a3cfbd506a..000000000000 --- a/features/extra/world.js +++ /dev/null @@ -1,6 +0,0 @@ -const world = require("./helpers"); -const WorldConstructor = function WorldConstructor() { - return world; -}; - -exports.World = WorldConstructor; diff --git a/features/gamelift/gamelift.feature b/features/gamelift/gamelift.feature deleted file mode 100644 index 160033fe7270..000000000000 --- a/features/gamelift/gamelift.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@gamelift -Feature: - - I want to use Amazon GameLift - - Scenario: Making a request - Given I run the "listBuilds" operation - Then the request should be successful - And the value at "Builds" should be a list - - Scenario: Error handling - Given I run the "describeAlias" operation with params: - """ - { "AliasId": "fake_id" } - """ - Then the error code should be "InvalidRequestException" diff --git a/features/gamelift/step_definitions/gamelift.js b/features/gamelift/step_definitions/gamelift.js deleted file mode 100644 index 1b31fdfb5bd5..000000000000 --- a/features/gamelift/step_definitions/gamelift.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@gamelift" }, function (scenario, callback) { - const { GameLift } = require("../../../clients/client-gamelift"); - this.service = new GameLift({}); - callback(); -}); diff --git a/features/glacier/glacier.feature b/features/glacier/glacier.feature deleted file mode 100644 index d92ccc4c16c8..000000000000 --- a/features/glacier/glacier.feature +++ /dev/null @@ -1,47 +0,0 @@ -# language: en -@glacier -Feature: Amazon Glacier - - I want to use Amazon Glacier - - @vault - Scenario: Creating a vault - Given I have a Glacier vault - When I describe the Glacier vault - Then the result should contain a property NumberOfArchives with a number - - @archive - Scenario: Uploading an archive - Given I have a Glacier vault - When I upload a 0.25MB Glacier archive to the vault - Then the result should contain the Glacier archive ID - And the result should contain the same tree hash checksum - And I delete the Glacier archive - - @multipart - Scenario: Multi-part upload - Given I have a Glacier vault - When I initiate a Glacier multi-part upload on a 2.5MB archive in 1MB chunks - Then the result should contain the Glacier multi-part upload ID - And I send the Glacier archive data in chunks - And I complete the Glacier multi-part upload - Then the result should contain the Glacier archive ID - And the result should contain the same tree hash checksum - And I delete the Glacier archive - - @error - Scenario: Error handling - Given I have a Glacier vault - And I upload a 0.05MB Glacier archive to the vault with incorrect checksum - Then the error code should be "InvalidParameterValueException" - And the error message should match: - """ - Checksum mismatch: - """ - - When I upload a 0.05MB Glacier archive to the vault with invalid checksum - Then the error code should be "InvalidParameterValueException" - And the error message should equal: - """ - Invalid x-amz-sha256-tree-hash: 000 - """ diff --git a/features/glacier/step_definitions/glacier.js b/features/glacier/step_definitions/glacier.js deleted file mode 100644 index 122cc25c4b28..000000000000 --- a/features/glacier/step_definitions/glacier.js +++ /dev/null @@ -1,135 +0,0 @@ -const { Before, Given, Then, When } = require("@cucumber/cucumber"); - -Before({ tags: "@glacier" }, function (scenario, callback) { - const { Glacier } = require("../../../clients/client-glacier"); - this.service = new Glacier({}); - callback(); -}); - -Given("I have a Glacier vault", function (callback) { - this.vaultName = "aws-sdk-js-integration"; - const params = { - vaultName: this.vaultName, - }; - this.request(null, "createVault", params, callback, false); -}); - -Given( - /^I upload a (\d+(?:\.\d+)?)MB Glacier archive to the vault( with (?:invalid|incorrect) checksum)?$/, - function (size, invalid, callback) { - const data = Buffer.alloc(parseFloat(size) * 1024 * 1024); - data.fill("0"); - const params = { - vaultName: this.vaultName, - body: data, - }; - // Computed by running bodyChecksumGenerator from body-checksum-node - this.treeHash = "6faefade5a638cd3545d638dd5754763658e32209e69420cb559b7650d4bf93a"; - if (invalid) { - if (invalid.match("invalid")) params.checksum = "000"; - else params.checksum = "00000000000000000000000000000000"; - } - this.request(null, "uploadArchive", params, callback, false); - } -); - -Then("the result should contain the Glacier archive ID", function (callback) { - this.archiveId = this.data.archiveId; - callback(); -}); - -Then("the result should contain the same tree hash checksum", function (callback) { - this.assert.equal(this.data.checksum, this.treeHash); - callback(); -}); - -When("I describe the Glacier vault", function (callback) { - const params = { - vaultName: this.vaultName, - }; - this.request(null, "describeVault", params, callback); -}); - -Then("I delete the Glacier archive", function (callback) { - const params = { - vaultName: this.vaultName, - archiveId: this.archiveId, - }; - this.request(null, "deleteArchive", params, callback); -}); - -Then("I delete the Glacier vault", function (callback) { - const params = { - vaultName: this.vaultName, - }; - this.eventually(callback, function (next) { - this.request(null, "deleteVault", params, next); - }); -}); - -When( - /^I initiate a Glacier multi-part upload on a (\d+(?:\.\d+)?)MB archive in (\d+)MB chunks$/, - function (totalSize, partSize, callback) { - // setup multi-part upload - this.uploadData = Buffer.alloc(totalSize * 1024 * 1024); - this.uploadData.fill("0"); - // Computed by running bodyChecksumGenerator from body-checksum-node - this.treeHash = "86118ad0c187fd240db59a37360e0e7f8a3a0c608eed740b4cd7b4271ab45171"; - this.partCounter = 0; - this.partSize = partSize * 1024 * 1024; - - const params = { - vaultName: this.vaultName, - partSize: this.partSize.toString(), - }; - this.request(null, "initiateMultipartUpload", params, callback); - } -); - -Then("the result should contain the Glacier multi-part upload ID", function (callback) { - this.uploadId = this.data.uploadId; - callback(); -}); - -Then("I send the next part", function (callback) { - const start = this.partCounter; - const end = Math.min(start + this.partSize, this.uploadData.length); - const buf = this.uploadData.slice(start, end); - const range = "bytes " + start + "-" + (end - 1) + "/*"; - const params = { - vaultName: this.vaultName, - uploadId: this.uploadId, - range: range, - body: buf, - }; - this.request(null, "uploadMultipartPart", params, callback); - this.partCounter += this.partSize; -}); - -Then("I send the Glacier archive data in chunks", function (callback) { - let numPartsLeft = Math.ceil(this.uploadData.length / this.partSize); - for (let i = 0; i < this.uploadData.length; i += this.partSize) { - const end = Math.min(i + this.partSize, this.uploadData.length); - const buf = this.uploadData.slice(i, end); - const range = "bytes " + i + "-" + (end - 1) + "/*"; - const params = { - vaultName: this.vaultName, - uploadId: this.uploadId, - range: range, - body: buf, - }; - this.service.uploadMultipartPart(params, function () { - if (--numPartsLeft === 0) callback(); - }); - } -}); - -Then("I complete the Glacier multi-part upload", function (callback) { - const params = { - vaultName: this.vaultName, - uploadId: this.uploadId, - archiveSize: this.uploadData.length.toString(), - checksum: this.treeHash, - }; - this.request(null, "completeMultipartUpload", params, callback); -}); diff --git a/features/iam/iam.feature b/features/iam/iam.feature deleted file mode 100644 index 10030d98d74c..000000000000 --- a/features/iam/iam.feature +++ /dev/null @@ -1,20 +0,0 @@ -# language: en -@iam -Feature: IAM - - I want to use IAM - - Scenario: Users - Given I have an IAM username "js-test" - And I create an IAM user with the username - Then the IAM user should exist - - Scenario: Roles - Given I create an IAM role with name prefix "aws-sdk-js" - Then the IAM role should exist - - Scenario: Error handling - Given I have an IAM username "js-test-dupe" - And I create an IAM user with the username - And I create an IAM user with the username - Then the error code should be "EntityAlreadyExistsException" diff --git a/features/iam/step_definitions/iam.js b/features/iam/step_definitions/iam.js deleted file mode 100644 index f6b8976850ed..000000000000 --- a/features/iam/step_definitions/iam.js +++ /dev/null @@ -1,57 +0,0 @@ -const { After, Before, Given, Then } = require("@cucumber/cucumber"); - -Before({ tags: "@iam" }, function () { - const { IAM } = require("../../../clients/client-iam"); - this.iam = new IAM({}); -}); - -After({ tags: "@iam" }, async function () { - if (this.iamUser) { - await this.iam.deleteUser({ UserName: this.iamUser }); - this.iamUser = undefined; - } - if (this.iamRoleName) { - await this.iam.deleteRole({ RoleName: this.iamRoleName }); - this.iamRoleName = undefined; - } -}); - -Given("I have an IAM username {string}", function (name) { - this.iamUser = this.uniqueName(name); -}); - -Given("I create an IAM user with the username", async function () { - try { - const { User } = await this.iam.createUser({ UserName: this.iamUser }); - this.iamUserArn = User.Arn; - } catch (error) { - this.error = error; - } -}); - -Then("the IAM user should exist", async function () { - const { User } = await this.iam.getUser({ UserName: this.iamUser }); - this.assert.equal(User.UserName, this.iamUser); - this.assert.equal(User.Arn, this.iamUserArn); -}); - -Given("I create an IAM role with name prefix {string}", async function (name) { - this.iamRoleName = this.uniqueName(name); - - const assumeRolePolicyDocument = - '{"Version":"2008-10-17","Statement":[' + - '{"Effect":"Allow","Principal":{"Service":["ec2.amazonaws.com"]},' + - '"Action":["sts:AssumeRole"]}]}'; - const params = { - RoleName: this.iamRoleName, - AssumeRolePolicyDocument: assumeRolePolicyDocument, - }; - - this.data = await this.iam.createRole(params); - this.iamRoleArn = this.data.Role.Arn; -}); - -Then("the IAM role should exist", async function () { - const { Role } = await this.iam.getRole({ RoleName: this.iamRoleName }); - this.assert.equal(Role.RoleName, this.iamRoleName); -}); diff --git a/features/iot/iot.feature b/features/iot/iot.feature deleted file mode 100644 index 1479eab21457..000000000000 --- a/features/iot/iot.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@iot -Feature: - - I want to use AWS IoT - - Scenario: Making a request - Given I run the "listPolicies" operation - Then the request should be successful - And the value at "policies" should be a list - - Scenario: Error handling - Given I run the "describeCertificate" operation with params: - """ - { "certificateId": "fake_id" } - """ - Then the error code should be "InvalidRequestException" diff --git a/features/iot/step_definitions/iot.js b/features/iot/step_definitions/iot.js deleted file mode 100644 index aadf29c5d4a7..000000000000 --- a/features/iot/step_definitions/iot.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@iot" }, function (scenario, callback) { - const { IoT } = require("../../../clients/client-iot"); - this.service = new IoT({}); - callback(); -}); diff --git a/features/kinesis/kinesis.feature b/features/kinesis/kinesis.feature deleted file mode 100644 index 0e669ae7f527..000000000000 --- a/features/kinesis/kinesis.feature +++ /dev/null @@ -1,9 +0,0 @@ -# language: en -@kinesis -Feature: Amazon Kinesis - - I want to use Amazon Kinesis - -# Scenario: Error handling -# Given I try to describe a stream in Kinesis -# Then the error code should be "ResourceNotFoundException" diff --git a/features/kinesis/step_definitions/kinesis.js b/features/kinesis/step_definitions/kinesis.js deleted file mode 100644 index ea3c5af28bb0..000000000000 --- a/features/kinesis/step_definitions/kinesis.js +++ /dev/null @@ -1,11 +0,0 @@ -const { Before, Given } = require("@cucumber/cucumber"); - -Before({ tags: "@kinesis" }, function (scenario, callback) { - const { Kinesis } = require("../../../clients/client-kinesis"); - this.service = new Kinesis({}); - callback(); -}); - -Given("I try to describe a stream in Kinesis", function (callback) { - this.request(null, "describeStream", { StreamName: "XXINVALIDXX" }, callback, false); -}); diff --git a/features/kms/kms.feature b/features/kms/kms.feature deleted file mode 100644 index 713bebd4fae0..000000000000 --- a/features/kms/kms.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@kms -Feature: AWS Key Management Service - - I want to use AWS Key Management Service - - Scenario: List keys - Given I run the "listKeys" operation - Then the request should be successful - And the value at "Keys" should be a list - - Scenario: Error handling - Given I run the "createAlias" operation with params: - """ - { "AliasName": "alias", "TargetKeyId": "non-existent" } - """ - Then the error code should be "ValidationException" diff --git a/features/kms/step_definitions/kms.js b/features/kms/step_definitions/kms.js deleted file mode 100644 index ba1a745f8e73..000000000000 --- a/features/kms/step_definitions/kms.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@kms" }, function (scenario, callback) { - const { KMS } = require("../../../clients/client-kms"); - this.service = new KMS({}); - callback(); -}); diff --git a/features/lambda/lambda.feature b/features/lambda/lambda.feature deleted file mode 100644 index 364a1d6b47a1..000000000000 --- a/features/lambda/lambda.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@lambda -Feature: Amazon Lambda - - I want to use Amazon Lambda - - Scenario: Listing functions - Given I run the "listFunctions" operation - Then the request should be successful - And the value at "Functions" should be a list - - Scenario: Error handling - Given I run the "invoke" operation with params: - """ - { "FunctionName": "non-exist" } - """ - Then the error code should be "ResourceNotFoundException" diff --git a/features/lambda/step_definitions/lambda.js b/features/lambda/step_definitions/lambda.js deleted file mode 100644 index 35d9fb468663..000000000000 --- a/features/lambda/step_definitions/lambda.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@lambda" }, function (scenario, callback) { - const { Lambda } = require("../../../clients/client-lambda"); - this.service = new Lambda({}); - callback(); -}); diff --git a/features/pinpoint/pinpoint.feature b/features/pinpoint/pinpoint.feature deleted file mode 100644 index 7d15356e8a8c..000000000000 --- a/features/pinpoint/pinpoint.feature +++ /dev/null @@ -1,35 +0,0 @@ -# language: en -@pinpoint -Feature: Amazon Pinpoint - - I want to use Amazon Pinpoint - - Scenario: Putting events - Given I create an application - Given I run the "putEvents" operation with EventsRequest: - """ - { - "BatchItem": { - "foo": { - "Endpoint": { - "Address": "fooEndpointAddress" - }, - "Events": { - "foo": { - "EventType":"_session.start", - "Timestamp":"2015-03-19T17:32:40.577Z" - } - } - } - } - } - """ - Then the request should be successful - And I delete the application - - Scenario: Error handling - Given I run the "putEvents" operation with params: - """ - {"Events": [{"eventType": "test", "timestamp": "test"}], "ApplicationId": "test"} - """ - Then the error code should be "NotFoundException" diff --git a/features/pinpoint/step_definitions/pinpoint.js b/features/pinpoint/step_definitions/pinpoint.js deleted file mode 100644 index 409fd03a8149..000000000000 --- a/features/pinpoint/step_definitions/pinpoint.js +++ /dev/null @@ -1,47 +0,0 @@ -const { Before, Given } = require("@cucumber/cucumber"); - -Before({ tags: "@pinpoint" }, function (scenario, callback) { - const { Pinpoint } = require("../../../clients/client-pinpoint"); - this.service = new Pinpoint({}); - callback(); -}); - -Given("I create an application", function (callback) { - const params = { - CreateApplicationRequest: { - Name: this.uniqueName("aws-sdk-js-integration"), - }, - }; - this.request(null, "createApp", params, function (err, data) { - if (err) { - callback(err); - } - this.applicationId = this.data.ApplicationResponse.Id; - callback(); - }); -}); - -Given('I run the "putEvents" operation with EventsRequest:', function (eventsRequest, callback) { - this.request( - null, - "putEvents", - { - ApplicationId: this.applicationId, - EventsRequest: JSON.parse(eventsRequest), - }, - callback, - false - ); -}); - -Given("I delete the application", function (callback) { - this.request( - null, - "deleteApp", - { - ApplicationId: this.applicationId, - }, - callback, - false - ); -}); diff --git a/features/rds/rds.feature b/features/rds/rds.feature deleted file mode 100644 index 21f0795bc63d..000000000000 --- a/features/rds/rds.feature +++ /dev/null @@ -1,29 +0,0 @@ -# language: en -@rds -Feature: Amazon Relational Database Service - - I want to use Amazon Relational Database Service - - Scenario: Describe DB security group - Given I create a RDS security group with prefix name "aws-sdk-js-rds-e2e" - Given I run the "describeDBSecurityGroups" operation - Then the request should be successful - And the value at "DBSecurityGroups" should be a list - And the value at "DBSecurityGroups" should contain "DBSecurityGroupDescription" with "Description" - - Scenario: Error handling - Given I create a RDS security group with prefix name "" - Then the error code should be "InvalidParameterValue" - And the error status code should be 400 - - # @pagination - # Scenario: Paginating responses - # Given I paginate the "describeReservedDBInstancesOfferings" operation with limit 100 - # Then I should get more than one page - # And I should get numPages - 1 markers - # And the last page should not contain a marker - - # @pagination - # Scenario: Paginating responses (with callback) - # Given I paginate the "describeReservedDBInstancesOfferings" operation asynchronously with limit 100 - # Then I should be able to asynchronously paginate all pages diff --git a/features/rds/step_definitions/rds.js b/features/rds/step_definitions/rds.js deleted file mode 100644 index fbd2265d47e3..000000000000 --- a/features/rds/step_definitions/rds.js +++ /dev/null @@ -1,85 +0,0 @@ -const jmespath = require("jmespath"); -const { After, Before, Given, Then } = require("@cucumber/cucumber"); - -const dbsgNames = []; - -Before({ tags: "@rds" }, function (scenario, callback) { - const { RDS } = require("../../../clients/client-rds"); - this.service = new RDS({}); - callback(); -}); - -After({ tags: "@rds" }, async function () { - while (dbsgNames.length) { - const name = dbsgNames.pop(); - if (name) { - await this.service.deleteDBSecurityGroup({ - DBSecurityGroupName: name, - }); - } - } -}); - -Given("I create a RDS security group with prefix name {string}", function (prefix, callback) { - this.dbGroupName = this.uniqueName(prefix); - dbsgNames.push(this.dbGroupName); - const params = { - DBSecurityGroupDescription: "Description", - DBSecurityGroupName: this.dbGroupName, - }; - this.request(null, "createDBSecurityGroup", params, callback, false); -}); - -Then("the value at {string} should contain {string} with {string}", function (path, key, value, callback) { - const member = jmespath.search(this.data, path); - let containDefault = false; - member.forEach(function (config) { - if (config[key] === value) { - containDefault = true; - } - }); - this.assert.ok( - containDefault === true, - `No ${path} has member key ${key} of the value ${value}: ${JSON.stringify(this.data, null, 2)}` - ); - callback(); -}); - -Given("I paginate the {string} operation asynchronously with limit {int}", function (operation, limit, callback) { - const maxPages = 3; - limit = parseInt(limit); - - const world = this; - this.numPages = 0; - this.numMarkers = 0; - this.operation = operation; - this.paginationConfig = this.service.paginationConfig(operation); - this.params = this.params || {}; - this.finishedPagination = false; - - const marker = this.paginationConfig.outputToken; - if (this.paginationConfig.limitKey) { - this.params[this.paginationConfig.limitKey] = limit; - } - this.service[operation](this.params).eachPage(function (err, data, done) { - process.nextTick(function () { - if (err) callback(err); - else if (data === null || world.numPages === maxPages) { - world.finishedPagination = true; - callback(); - return false; - } else { - if (data[marker]) world.numMarkers++; - world.numPages++; - world.data = data; - } - - done(); // start getting next page - }); - }); -}); - -Then("I should be able to asynchronously paginate all pages", function (callback) { - this.assert.equal(this.finishedPagination, true); - callback(); -}); diff --git a/features/redshift/redshift.feature b/features/redshift/redshift.feature deleted file mode 100644 index e4b29bea30be..000000000000 --- a/features/redshift/redshift.feature +++ /dev/null @@ -1,18 +0,0 @@ -# language: en -@redshift -Feature: Amazon Redshift - - I want to use Amazon Redshift - - Scenario: Describe cluster parameter groups - Given I run the "describeClusterParameterGroups" operation - Then the request should be successful - And the value at "ParameterGroups" should be a list - - Scenario: Error handling - Given I create a Redshift cluster parameter group with prefix name "" - Then the error code should be "InvalidParameterValue" - Then the error message should contain: - """ - The parameter DBParameterGroupName must be provided and must not be blank - """ diff --git a/features/redshift/step_definitions/redshift.js b/features/redshift/step_definitions/redshift.js deleted file mode 100644 index 162ee388fa19..000000000000 --- a/features/redshift/step_definitions/redshift.js +++ /dev/null @@ -1,17 +0,0 @@ -const { Before, Given } = require("@cucumber/cucumber"); - -Before({ tags: "@redshift" }, function (scenario, callback) { - const { Redshift } = require("../../../clients/client-redshift"); - this.service = new Redshift({}); - callback(); -}); - -Given("I create a Redshift cluster parameter group with prefix name {string}", function (prefix, callback) { - this.parameterGroupName = this.uniqueName(prefix); - const params = { - Description: "Description", - ParameterGroupName: this.parameterGroupName, - ParameterGroupFamily: "redshift-1.0", - }; - this.request(null, "createClusterParameterGroup", params, callback, false); -}); diff --git a/features/route53/route53.feature b/features/route53/route53.feature deleted file mode 100644 index 16666328885d..000000000000 --- a/features/route53/route53.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@route53 -Feature: Amazon Route 53 - - I want to use Amazon Route 53 - - Scenario: Making a request - Given I run the "listHostedZones" operation - Then the request should be successful - And the value at "HostedZones" should be a list - - Scenario: Error handling - Given I run the "getHostedZone" operation with params: - """ - { "Id": "fake-zone" } - """ - Then the error code should be "NoSuchHostedZone" diff --git a/features/route53/step_definitions/route53.js b/features/route53/step_definitions/route53.js deleted file mode 100644 index a2e468201576..000000000000 --- a/features/route53/step_definitions/route53.js +++ /dev/null @@ -1,123 +0,0 @@ -const { Before, Then, When } = require("@cucumber/cucumber"); - -Before({ tags: "@route53" }, function (scenario, callback) { - const { Route53 } = require("../../../clients/client-route-53"); - this.service = new Route53({}); - callback(); -}); - -When("I create a Route53 hosted zone with name prefix {string}", function (prefix, callback) { - this.zoneName = "zone1.example.com"; - const params = { - Name: this.zoneName, - CallerReference: this.uniqueName(prefix), - HostedZoneConfig: { - Comment: "A comment about the zone", - }, - }; - this.request(null, "createHostedZone", params, callback, false); -}); - -Then("the result should contain the hosted zone ID", function (callback) { - this.hostedZoneId = this.data.HostedZone.Id; - callback(); -}); - -Then("the result should contain the change ID", function (callback) { - this.changeInfoId = this.data.ChangeInfo.Id; - callback(); -}); - -Then("the result should contain the hosted zone name", function (callback) { - this.assert.equal(this.data.HostedZone.Name, this.zoneName + "."); - callback(); -}); - -When("I get information about the Route53 change ID", function (callback) { - this.request( - null, - "getChange", - { - Id: this.changeInfoId, - }, - callback - ); -}); - -Then("the change status should be PENDING or INSYNC", function (callback) { - this.assert.match(this.data.ChangeInfo.Status, "(PENDING|INSYNC)"); - callback(); -}); - -When("I get information about the Route53 hosted zone ID", function (callback) { - this.request( - null, - "getHostedZone", - { - Id: this.hostedZoneId, - }, - callback - ); -}); - -Then("the result should contain multiple nameservers", function (callback) { - this.assert.compare(this.data.DelegationSet.NameServers.length, ">=", 0); - this.assert.equal(typeof this.data.DelegationSet.NameServers[0], "string"); - callback(); -}); - -Then("I delete the Route53 hosted zone", function (callback) { - this.request( - null, - "deleteHostedZone", - { - Id: this.hostedZoneId, - }, - callback - ); -}); - -When("I create a Route53 TCP health check with name prefix {string}", function (prefix, callback) { - const params = { - CallerReference: this.uniqueName(prefix), - HealthCheckConfig: { - IPAddress: "192.0.43.10", // example.com - Port: 80, - Type: "TCP", - }, - }; - this.request(null, "createHealthCheck", params, callback); -}); - -Then("the result should contain health check information", function (callback) { - this.healthCheckInfo = this.data.HealthCheck; - callback(); -}); - -Then("the result should contain the health check ID", function (callback) { - this.healthCheckId = this.data.HealthCheck.Id; - callback(); -}); - -When("I get information about the health check ID", function (callback) { - const params = { - HealthCheckId: this.healthCheckId, - }; - this.request(null, "getHealthCheck", params, callback); -}); - -Then("the result should contain the previous health check information", function (callback) { - this.assert.deepEqual(this.data.HealthCheck, this.healthCheckInfo); - callback(); -}); - -Then("I delete the Route53 TCP health check", function (callback) { - const params = { - HealthCheckId: this.healthCheckId, - }; - this.request(null, "deleteHealthCheck", params, callback); -}); - -When("I list Route53 hosted zones", function (callback) { - this.request(null, "listHostedZones", {}, callback); -}); diff --git a/features/route53domains/route53domains.feature b/features/route53domains/route53domains.feature deleted file mode 100644 index aaa5897dfd8b..000000000000 --- a/features/route53domains/route53domains.feature +++ /dev/null @@ -1,14 +0,0 @@ -# language: en -@route53domains -Feature: Amazon Route 53 Domains - - I want to use Amazon Route 53 Domains - - Scenario: Feature - Given I list Route53 domains - Then the request should be successful - And the value at "Domains" should be a list - - Scenario: Error handling - Given I try to register a Route53 domain with invalid parameters - Then the error code should be "InvalidInput" diff --git a/features/route53domains/step_definitions/route53domains.js b/features/route53domains/step_definitions/route53domains.js deleted file mode 100644 index 89e582559f84..000000000000 --- a/features/route53domains/step_definitions/route53domains.js +++ /dev/null @@ -1,22 +0,0 @@ -const { Before, Given } = require("@cucumber/cucumber"); - -Before({ tags: "@route53domains" }, function (scenario, callback) { - const { Route53Domains } = require("../../../clients/client-route-53-domains"); - this.service = new Route53Domains({ region: "us-east-1" }); - callback(); -}); - -Given("I list Route53 domains", function (callback) { - this.request(null, "listDomains", {}, callback); -}); - -Given("I try to register a Route53 domain with invalid parameters", function (callback) { - const params = { - DomainName: "example.com", - DurationInYears: 1, - AdminContact: {}, - RegistrantContact: {}, - TechContact: {}, - }; - this.request(null, "registerDomain", params, callback, false); -}); diff --git a/features/sagemaker/sagemaker.feature b/features/sagemaker/sagemaker.feature deleted file mode 100644 index 4d6c6fffb639..000000000000 --- a/features/sagemaker/sagemaker.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@sagemaker -Feature: Amazon SageMaker - - I want to use Amazon SageMaker - - Scenario: Listing Endpoints - Given I run the "listEndpoints" operation - Then the request should be successful - And the value at "Endpoints" should be a list - - Scenario: Error handling - Given I run the "describeEndpoint" operation with params: - """ - { "EndpointName": "non-existent" } - """ - Then the error code should be "ValidationException" diff --git a/features/sagemaker/step_definitions/sagemaker.js b/features/sagemaker/step_definitions/sagemaker.js deleted file mode 100644 index 8442a940fc26..000000000000 --- a/features/sagemaker/step_definitions/sagemaker.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@sagemaker" }, function (scenario, callback) { - const { SageMaker } = require("../../../clients/client-sagemaker"); - this.service = new SageMaker({}); - callback(); -}); diff --git a/features/ses/ses.feature b/features/ses/ses.feature deleted file mode 100644 index 4351923a341c..000000000000 --- a/features/ses/ses.feature +++ /dev/null @@ -1,20 +0,0 @@ -# language: en -@ses -Feature: SES - - I want to use Simple Email Service. - - Scenario: Check quota - When I check quota - Then the result should include number "SentLast24Hours" - And the result should include number "MaxSendRate" - - Scenario: Verify email - When I ask to verify the email address "foo@example.com" - Then the status code should be 200 - - Scenario: Rescue SES InvalidParameterValue - When I ask to verify the email address "abc123" - Then I should get the error: - | name | message | - | InvalidParameterValue | Invalid email address. | diff --git a/features/ses/step_definitions/ses.js b/features/ses/step_definitions/ses.js deleted file mode 100644 index f03dfaa6de52..000000000000 --- a/features/ses/step_definitions/ses.js +++ /dev/null @@ -1,31 +0,0 @@ -const { Before, Then, When } = require("@cucumber/cucumber"); - -Before({ tags: "@ses" }, function (scenario, callback) { - const { SES } = require("../../../clients/client-ses"); - this.service = new SES({}); - callback(); -}); - -When("I check quota", function (next) { - this.request(null, "getSendQuota", {}, next); -}); - -Then("the result should include {word} {string}", function (type, attr, next) { - if (this.data[attr] === undefined) next.fail("Missing " + attr); - if (typeof this.data[attr] !== type) next.fail("Incorrect type " + attr); - next(); -}); - -When("I ask to verify the email address {string}", function (email, next) { - this.request( - null, - "verifyEmailAddress", - { - EmailAddress: email, - }, - next, - function () { - // do nothing - } - ); -}); diff --git a/features/sns/sns.feature b/features/sns/sns.feature deleted file mode 100644 index 5db78cb87640..000000000000 --- a/features/sns/sns.feature +++ /dev/null @@ -1,14 +0,0 @@ -# language: en -@sns -Feature: Simple Notification Service - - I want to use Amazon Simple Notification Service - - Scenario: Topics - Given I create an SNS topic with prefix "aws-js-sdk" - And I list the SNS topics - Then the list should contain the topic ARN - - Scenario: Error handling - Given I get SNS topic attributes with an invalid ARN - Then the error code should be "InvalidParameterException" diff --git a/features/sns/step_definitions/sns.js b/features/sns/step_definitions/sns.js deleted file mode 100644 index 97801284d205..000000000000 --- a/features/sns/step_definitions/sns.js +++ /dev/null @@ -1,38 +0,0 @@ -const { After, Before, Given, Then } = require("@cucumber/cucumber"); - -Before({ tags: "@sns" }, function () { - const { SNS } = require("../../../clients/client-sns"); - this.service = new SNS({}); -}); - -After({ tags: "@sns" }, async function () { - if (this.topicArn) { - await this.service.deleteTopic({ TopicArn: this.topicArn }); - this.topicArn = undefined; - } -}); - -Given("I create an SNS topic with prefix {string}", async function (prefix) { - const topicName = this.uniqueName(prefix); - const { TopicArn } = await this.service.createTopic({ Name: topicName }); - this.topicArn = TopicArn; -}); - -Given("I list the SNS topics", async function () { - this.data = await this.service.listTopics({}); -}); - -Then("the list should contain the topic ARN", function () { - const arn = this.topicArn; - this.assert.contains(this.data.Topics, function (topic) { - return topic.TopicArn === arn; - }); -}); - -Given("I get SNS topic attributes with an invalid ARN", async function () { - try { - await this.service.getTopicAttributes({ TopicArn: "INVALID" }); - } catch (error) { - this.error = error; - } -}); diff --git a/features/sqs/messages.feature b/features/sqs/messages.feature deleted file mode 100644 index 23612b4de385..000000000000 --- a/features/sqs/messages.feature +++ /dev/null @@ -1,19 +0,0 @@ -# language: en -@sqs @messages -Feature: SQS Messages - - I want to be able to send and process messages. - - Scenario: Send an SQS message - Given I create a queue with the prefix name "aws-js-sdk" - When I send the message "HELLO" - Then the result should include a message ID - And the result should have an MD5 digest of "eb61eead90e3b899c6bcbe27ac581660" - And I should eventually be able to receive "HELLO" from the queue - - Scenario: Binary payloads - Given I create a queue with the prefix name "aws-js-sdk" - When I send the message "HELLO" with a binary attribute - Then the result should include a message ID - And the result should have an MD5 digest of "eb61eead90e3b899c6bcbe27ac581660" - And I should eventually be able to receive "HELLO" from the queue with a binary attribute diff --git a/features/sqs/queues.feature b/features/sqs/queues.feature deleted file mode 100644 index 202ae05a95aa..000000000000 --- a/features/sqs/queues.feature +++ /dev/null @@ -1,10 +0,0 @@ -# language: en -@sqs @queues -Feature: SQS Queues - - I want to be able to create, list and delete queues. - - Scenario: Creating and deleting queues - Given I create a queue with the prefix name "aws-js-sdk" - And I create a queue with the prefix name "aws-js-sdk" - Then list queues should eventually return the queue urls diff --git a/features/sqs/step_definitions/messages.js b/features/sqs/step_definitions/messages.js deleted file mode 100644 index 9a99b557ac56..000000000000 --- a/features/sqs/step_definitions/messages.js +++ /dev/null @@ -1,51 +0,0 @@ -const { Then, When } = require("@cucumber/cucumber"); - -When("I send the message {string}", function (message, callback) { - this.request(null, "sendMessage", { QueueUrl: this.queueUrl, MessageBody: message }, callback); -}); - -Then("the result should include a message ID", function (callback) { - this.assert.compare(this.data.MessageId.length, ">", 0); - callback(); -}); - -Then("the result should have an MD5 digest of {string}", function (digest, callback) { - this.assert.equal(this.data.MD5OfMessageBody, digest); - callback(); -}); - -Then("I should eventually be able to receive {string} from the queue", function (message, callback) { - this.eventually(callback, function (next) { - next.condition = function () { - return this.data.Messages[0].Body === message; - }; - this.request(null, "receiveMessage", { QueueUrl: this.queueUrl }, next); - }); -}); - -When("I send the message {string} with a binary attribute", function (message, callback) { - const params = { - QueueUrl: this.queueUrl, - MessageBody: message, - MessageAttributes: { - binary: { DataType: "Binary", BinaryValue: Buffer.from([1, 2, 3]) }, - }, - }; - this.request(null, "sendMessage", params, callback); -}); - -Then( - "I should eventually be able to receive {string} from the queue with a binary attribute", - function (message, callback) { - this.eventually(callback, function (next) { - next.condition = function () { - return this.data.Messages[0].MessageAttributes.binary.BinaryValue.toString() === "1,2,3"; - }; - const params = { - QueueUrl: this.queueUrl, - MessageAttributeNames: ["binary"], - }; - this.request(null, "receiveMessage", params, next); - }); - } -); diff --git a/features/sqs/step_definitions/queues.js b/features/sqs/step_definitions/queues.js deleted file mode 100644 index 44dd37412104..000000000000 --- a/features/sqs/step_definitions/queues.js +++ /dev/null @@ -1,30 +0,0 @@ -const { Given, Then } = require("@cucumber/cucumber"); - -Given("I create a queue with the prefix name {string}", async function (prefix) { - const name = this.uniqueName(prefix); - const response = await this.service.createQueue({ QueueName: name }); - this.queueUrl = response.QueueUrl; - this.createdQueues.push(this.queueUrl); -}); - -Then("list queues should eventually return the queue urls", function (callback) { - this.eventually( - callback, - function (next) { - next.condition = function () { - let matchingCount = 0; - for (let i = 0; i < this.createdQueues.length; ++i) { - for (let j = 0; j < this.data.QueueUrls.length; ++j) { - if (this.createdQueues[i] == this.data.QueueUrls[j]) { - matchingCount++; - } - } - } - return matchingCount == this.createdQueues.length; - }; - - this.request(null, "listQueues", {}, next); - }, - { maxTime: 60 } - ); -}); diff --git a/features/sqs/step_definitions/sqs.js b/features/sqs/step_definitions/sqs.js deleted file mode 100644 index 9813ced545ce..000000000000 --- a/features/sqs/step_definitions/sqs.js +++ /dev/null @@ -1,13 +0,0 @@ -const { Before, After } = require("@cucumber/cucumber"); - -Before({ tags: "@sqs" }, function () { - const { SQS } = require("../../../clients/client-sqs"); - this.service = new SQS({}); - this.createdQueues = []; -}); - -After({ tags: "@sqs" }, async function () { - for (const queueUrl of this.createdQueues) { - await this.service.deleteQueue({ QueueUrl: queueUrl }); - } -}); diff --git a/features/ssm/ssm.feature b/features/ssm/ssm.feature deleted file mode 100644 index e68f278e6ebe..000000000000 --- a/features/ssm/ssm.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@ssm -Feature: - - I want to use AWS Simple Systems Management - - Scenario: Listing Documents - Given I run the "listDocuments" operation - Then the request should be successful - And the value at "DocumentIdentifiers" should be a list - - Scenario: Error handling - Given I run the "describeDocument" operation with params: - """ - {"Name": "foo-bar-baz" } - """ - Then the error code should be "InvalidDocument" diff --git a/features/ssm/step_definitions/ssm.js b/features/ssm/step_definitions/ssm.js deleted file mode 100644 index b3b5daed0e39..000000000000 --- a/features/ssm/step_definitions/ssm.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@ssm" }, function (scenario, callback) { - const { SSM } = require("../../../clients/client-ssm"); - this.service = new SSM({}); - callback(); -}); diff --git a/features/storagegateway/step_definitions/storagegateway.js b/features/storagegateway/step_definitions/storagegateway.js deleted file mode 100644 index c405d92e546e..000000000000 --- a/features/storagegateway/step_definitions/storagegateway.js +++ /dev/null @@ -1,17 +0,0 @@ -const { Before, When } = require("@cucumber/cucumber"); - -Before({ tags: "@storagegateway" }, function (scenario, callback) { - const { StorageGateway } = require("../../../clients/client-storage-gateway"); - this.service = new StorageGateway({ region: "us-east-1" }); - callback(); -}); - -When("I try to activate a Storage Gateway", function (callback) { - const params = { - ActivationKey: "INVALIDKEY", - GatewayName: this.uniqueName("aws-sdk-js"), - GatewayTimezone: "GMT-5:00", - GatewayRegion: "us-east-1", - }; - this.request(null, "activateGateway", params, callback, false); -}); diff --git a/features/storagegateway/storagegateway.feature b/features/storagegateway/storagegateway.feature deleted file mode 100644 index b16d7ce3bc9b..000000000000 --- a/features/storagegateway/storagegateway.feature +++ /dev/null @@ -1,15 +0,0 @@ -# language: en -@storagegateway -Feature: AWS Storage Gateway - - I want to use AWS Storage Gateway - - Scenario: Listing Gateways - Given I run the "listGateways" operation - Then the request should be successful - And the value at "Gateways" should be a list - - Scenario: Activating a Gateway - When I try to activate a Storage Gateway - Then the error code should be "InvalidGatewayRequestException" - And the error status code should be 400 diff --git a/features/sts/step_definitions/sts.js b/features/sts/step_definitions/sts.js deleted file mode 100644 index 30a159a8b161..000000000000 --- a/features/sts/step_definitions/sts.js +++ /dev/null @@ -1,39 +0,0 @@ -const { Before, Given } = require("@cucumber/cucumber"); - -Before({ tags: "@sts" }, function (scenario, callback) { - const { STS } = require("../../../clients/client-sts"); - this.service = new STS({}); - callback(); -}); - -Given("I get an STS session token with a duration of {int} seconds", function (duration, callback) { - this.request( - null, - "getSessionToken", - { - DurationSeconds: parseInt(duration), - }, - callback, - false - ); -}); - -Given("I try to assume role with web identity", function (callback) { - const params = { - RoleArn: "arn:aws:iam::123456789:role/WebIdentity", - RoleSessionName: "name", - WebIdentityToken: "token", - }; - this.request(null, "assumeRoleWithWebIdentity", params, callback, false); -}); - -Given("I try to assume role with SAML", function (callback) { - const arn = "arn:aws:iam::123456789:role/Role"; - const token = "TOKENVALUETOKENVALUETOKENVALUETOKENVALUE"; - const params = { - RoleArn: arn, - PrincipalArn: arn, - SAMLAssertion: token, - }; - this.request(null, "assumeRoleWithSAML", params, callback, false); -}); diff --git a/features/sts/sts.feature b/features/sts/sts.feature deleted file mode 100644 index c9652a0e37a4..000000000000 --- a/features/sts/sts.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@sts -Feature: AWS Security Token Service - - I want to use AWS Security Token Service - - @requiresakid @nosession - Scenario: Get caller identity - Given I run the "getCallerIdentity" operation - Then the request should be successful - Then the result should contain a property Account with a string - Then the result should contain a property Arn with a string - Then the result should contain a property UserId with a string - - Scenario: Error handling - Given I get an STS session token with a duration of 60 seconds - Then the error code should be "ValidationError" diff --git a/features/swf/step_definitions/swf.js b/features/swf/step_definitions/swf.js deleted file mode 100644 index efb68a767d6f..000000000000 --- a/features/swf/step_definitions/swf.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before, Given, Then, When } = require("@cucumber/cucumber"); - -Before({ tags: "@swf" }, function (scenario, callback) { - const { SWF } = require("../../../clients/client-swf"); - this.service = new SWF({}); - callback(); -}); diff --git a/features/swf/swf.feature b/features/swf/swf.feature deleted file mode 100644 index e30445e9e701..000000000000 --- a/features/swf/swf.feature +++ /dev/null @@ -1,20 +0,0 @@ -# language: en -@swf -Feature: Amazon Simple Workflow Service - - I want to use Amazon Simple Workflow Service - - Scenario: Listing domains - Given I run the "listDomains" operation with params: - """ - { "registrationStatus": "REGISTERED" } - """ - Then the request should be successful - And the value at "domainInfos" should be a list - - Scenario: Error handling - Given I run the "describeDomain" operation with params: - """ - { "name": "fake-domain" } - """ - Then the error code should be "UnknownResourceFault" diff --git a/features/waf/step_definitions/waf.js b/features/waf/step_definitions/waf.js deleted file mode 100644 index f2b51ff5ab00..000000000000 --- a/features/waf/step_definitions/waf.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@waf" }, function (scenario, callback) { - const { WAF } = require("../../../clients/client-waf"); - this.service = new WAF({}); - callback(); -}); diff --git a/features/waf/waf.feature b/features/waf/waf.feature deleted file mode 100644 index dcb79eed736d..000000000000 --- a/features/waf/waf.feature +++ /dev/null @@ -1,23 +0,0 @@ -# language: en -@waf -Feature: AWS WAF - - I want to use AWS WAF - - Scenario: Making a request - Given I run the "listRules" operation with params: - """ - { "Limit": 20 } - """ - Then the request should be successful - And the value at "Rules" should be a list - - Scenario: Error handling - Given I run the "createSqlInjectionMatchSet" operation with params: - """ - { - "Name": "fake_name", - "ChangeToken": "fake_token" - } - """ - Then the error code should be "WAFStaleDataException" diff --git a/features/workspaces/step_definitions/workspaces.js b/features/workspaces/step_definitions/workspaces.js deleted file mode 100644 index 15691e1f1f07..000000000000 --- a/features/workspaces/step_definitions/workspaces.js +++ /dev/null @@ -1,7 +0,0 @@ -const { Before } = require("@cucumber/cucumber"); - -Before({ tags: "@workspaces" }, function (scenario, callback) { - const { WorkSpaces } = require("../../../clients/client-workspaces"); - this.service = new WorkSpaces({}); - callback(); -}); diff --git a/features/workspaces/workspaces.feature b/features/workspaces/workspaces.feature deleted file mode 100644 index 3b0d52b4c516..000000000000 --- a/features/workspaces/workspaces.feature +++ /dev/null @@ -1,17 +0,0 @@ -# language: en -@workspaces -Feature: Amazon WorkSpaces - - I want to use Amazon WorkSpaces - - Scenario: Describing workspaces - Given I run the "describeWorkspaces" operation - Then the request should be successful - And the value at "Workspaces" should be a list - - Scenario: Error handling - Given I run the "rebuildWorkspaces" operation with params: - """ - { "RebuildWorkspaceRequests": [] } - """ - Then the error code should be "ValidationException" diff --git a/package.json b/package.json index 24f5db476688..6d5c09aa020a 100644 --- a/package.json +++ b/package.json @@ -39,9 +39,8 @@ "test:all": "yarn build:all && jest --passWithNoTests && lerna run test --scope '@aws-sdk/{fetch-http-handler,hash-blob-browser}' && yarn test:versions && yarn test:integration", "test:ci": "lerna run test --since origin/main", "test:e2e": "make test-e2e && node ./tests/canary/canary", - "test:e2e:legacy": "cucumber-js --fail-fast", - "test:e2e:legacy:preview": "./tests/e2e-legacy/preview.mjs", - "test:e2e:legacy:since:release": "./tests/e2e-legacy/since-release.mjs", + "test:e2e:legacy:preview": "exit 0", + "test:e2e:legacy:since:release": "exit 0", "test:functional": "jest --passWithNoTests --config tests/functional/jest.config.js && lerna run test --scope \"@aws-sdk/client-*\"", "test:integration": "make test-integration", "test:integration:legacy": "yarn test:e2e:legacy", @@ -66,8 +65,6 @@ "devDependencies": { "@commitlint/cli": "17.0.2", "@commitlint/config-conventional": "17.0.2", - "@cucumber/cucumber": "8.5.3", - "@cucumber/pretty-formatter": "^1.0.0", "@fastify/formbody": "^7.4.0", "@microsoft/api-extractor": "7.52.7", "@mixer/parallel-prettier": "2.0.3", diff --git a/tests/e2e-legacy/getAllTags.mjs b/tests/e2e-legacy/getAllTags.mjs deleted file mode 100644 index 64bb97ea051e..000000000000 --- a/tests/e2e-legacy/getAllTags.mjs +++ /dev/null @@ -1,15 +0,0 @@ -import { join } from "path"; -import { execSync } from "child_process"; -import { getDirName } from "./getDirName.mjs"; - -const __dirname = getDirName(); -const FEATURES_FOLDER = join(__dirname, "..", "..", "features"); - -const execOptions = { - ...process, - cwd: __dirname, - encoding: "utf-8", -}; - -export const getAllTags = () => - execSync(`grep -h ^@ ${join(FEATURES_FOLDER, "**", "*.feature")}`, execOptions).split(/[\n ]/g); diff --git a/tests/e2e-legacy/getDirName.mjs b/tests/e2e-legacy/getDirName.mjs deleted file mode 100644 index 23750f15d8f3..000000000000 --- a/tests/e2e-legacy/getDirName.mjs +++ /dev/null @@ -1,4 +0,0 @@ -import { dirname } from "path"; -import { fileURLToPath } from "url"; - -export const getDirName = () => dirname(fileURLToPath(import.meta.url)); diff --git a/tests/e2e-legacy/getPackageTags.mjs b/tests/e2e-legacy/getPackageTags.mjs deleted file mode 100644 index 1237ef558880..000000000000 --- a/tests/e2e-legacy/getPackageTags.mjs +++ /dev/null @@ -1,5 +0,0 @@ -export const getPackageTags = (packages) => - packages - .map((name) => name.replace("@aws-sdk/client-", "")) - .map((name) => name.replace("-", "")) - .map((name) => `@${name}`); diff --git a/tests/e2e-legacy/preview.mjs b/tests/e2e-legacy/preview.mjs deleted file mode 100755 index 4bde8c05bfa2..000000000000 --- a/tests/e2e-legacy/preview.mjs +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env node - -import { execSync } from "child_process"; -import { getDirName } from "./getDirName.mjs"; -import { getAllTags } from "./getAllTags.mjs"; -import { getPackageTags } from "./getPackageTags.mjs"; -import { runTestForTags } from "./runTestForTags.mjs"; - -const __dirname = getDirName(); - -const execOptions = { ...process, cwd: __dirname, encoding: "utf-8" }; -const commitsSinceOriginHead = execSync(`git log --oneline origin/main..HEAD --format=%s`, execOptions).split("\n"); - -const updatedClientsSet = new Set(); -for (const commitMessage of commitsSinceOriginHead) { - const prefix = commitMessage.split(":")[0]; - const scope = prefix.substring(prefix.indexOf("(") + 1, prefix.indexOf(")")); - if (scope && scope.startsWith("client-")) { - updatedClientsSet.add(`@aws-sdk/${scope}`); - } -} - -const updatedClients = [...updatedClientsSet]; -console.info(`Updated packages: ${updatedClients}`); - -if (updatedClients.length === 0) { - console.info(`Couldn't find clients in commit messages:\n '${commitsSinceOriginHead.join("\n")}'`); - process.exit(0); -} - -const allTags = getAllTags(); -const changedPackageTags = getPackageTags(updatedClients); -const tagsToTest = changedPackageTags.filter((tag) => allTags.includes(tag)); -runTestForTags(tagsToTest); diff --git a/tests/e2e-legacy/runTestForTags.mjs b/tests/e2e-legacy/runTestForTags.mjs deleted file mode 100644 index 38fbebfe0a2b..000000000000 --- a/tests/e2e-legacy/runTestForTags.mjs +++ /dev/null @@ -1,26 +0,0 @@ -import { join, resolve } from "path"; -import { spawn } from "child_process"; -import { getDirName } from "./getDirName.mjs"; - -const __dirname = getDirName(); -const ROOT = resolve(join(__dirname, "..", "..")); - -export const runTestForTags = (tagsToTest) => { - if (tagsToTest.length === 0) { - console.info("No clients with e2e-legacy test cases have changed."); - return; - } - - // Cucumber requires cwd to contain the test cases. - const command = `${join("node_modules", ".bin", "cucumber-js")}`; - const args = ["--fail-fast", "-t", `"${tagsToTest.join(" or ")}"`]; - console.info(`Running cucumber test: \n${command} ${args.join(" ")}`); - - const execOptions = { ...process, cwd: ROOT, encoding: "utf-8", shell: true }; - const cucumber = spawn(command, args, execOptions); - cucumber.stdout.pipe(process.stdout); - cucumber.stderr.pipe(process.stderr); - cucumber.on("close", (code) => { - process.exit(code); - }); -}; diff --git a/tests/e2e-legacy/since-release.mjs b/tests/e2e-legacy/since-release.mjs deleted file mode 100755 index 8ec007ed82f9..000000000000 --- a/tests/e2e-legacy/since-release.mjs +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env node - -import { join } from "path"; -import { execSync } from "child_process"; -import { getDirName } from "./getDirName.mjs"; -import { getAllTags } from "./getAllTags.mjs"; -import { getPackageTags } from "./getPackageTags.mjs"; -import { runTestForTags } from "./runTestForTags.mjs"; - -const __dirname = getDirName(); -const ROOT_BIN = join(__dirname, "..", "..", "node_modules", ".bin"); - -console.info(`Looking for changed packages...`); -let changedPackages = []; -try { - const execOptions = { ...process, cwd: __dirname, encoding: "utf-8" }; - changedPackages = execSync(`${join(ROOT_BIN, "lerna")} changed`, execOptions).split("\n"); -} catch (e) { - // Swallow error because Lerna throws if no package changes. -} - -const allTags = getAllTags(); -const changedPackageTags = getPackageTags(changedPackages); -const tagsToTest = changedPackageTags.filter((tag) => allTags.includes(tag)); -runTestForTags(tagsToTest); diff --git a/yarn.lock b/yarn.lock index dc604fe5f592..5b6c366a34ea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25293,13 +25293,6 @@ __metadata: languageName: node linkType: hard -"@colors/colors@npm:1.5.0": - version: 1.5.0 - resolution: "@colors/colors@npm:1.5.0" - checksum: 10c0/eb42729851adca56d19a08e48d5a1e95efd2a32c55ae0323de8119052be0510d4b7a1611f2abcbf28c044a6c11e6b7d38f99fccdad7429300c37a8ea5fb95b44 - languageName: node - linkType: hard - "@commitlint/cli@npm:17.0.2": version: 17.0.2 resolution: "@commitlint/cli@npm:17.0.2" @@ -25506,172 +25499,6 @@ __metadata: languageName: node linkType: hard -"@cucumber/ci-environment@npm:9.1.0": - version: 9.1.0 - resolution: "@cucumber/ci-environment@npm:9.1.0" - checksum: 10c0/bdfd2c529434f09c871d2779200088cb4b858e4b490b98224d8d49c579ed8c8a13b5e2b6ddce20645d41bf8a5ac7b0952ebcda7a4207aa6cd6c9646077f5a8e0 - languageName: node - linkType: hard - -"@cucumber/cucumber-expressions@npm:16.0.0": - version: 16.0.0 - resolution: "@cucumber/cucumber-expressions@npm:16.0.0" - dependencies: - regexp-match-indices: "npm:1.0.2" - checksum: 10c0/b955c88ce49cf76b4d2c609b817931f9b4c5701b635326d9b185f86c8bf0a0f392c49522186846c7ccb5c1e737cc5eda4f1ca1e791e636e05ae185c6af4de3ed - languageName: node - linkType: hard - -"@cucumber/cucumber@npm:8.5.3": - version: 8.5.3 - resolution: "@cucumber/cucumber@npm:8.5.3" - dependencies: - "@cspotcode/source-map-support": "npm:^0.8.0" - "@cucumber/ci-environment": "npm:9.1.0" - "@cucumber/cucumber-expressions": "npm:16.0.0" - "@cucumber/gherkin": "npm:24.0.0" - "@cucumber/gherkin-streams": "npm:5.0.1" - "@cucumber/gherkin-utils": "npm:8.0.0" - "@cucumber/html-formatter": "npm:20.0.0" - "@cucumber/message-streams": "npm:4.0.1" - "@cucumber/messages": "npm:19.1.2" - "@cucumber/tag-expressions": "npm:4.1.0" - assertion-error-formatter: "npm:^3.0.0" - capital-case: "npm:^1.0.4" - chalk: "npm:^4.1.2" - cli-table3: "npm:0.6.2" - commander: "npm:^9.0.0" - duration: "npm:^0.2.2" - durations: "npm:^3.4.2" - figures: "npm:^3.2.0" - glob: "npm:^7.1.6" - has-ansi: "npm:^4.0.1" - indent-string: "npm:^4.0.0" - is-installed-globally: "npm:^0.4.0" - is-stream: "npm:^2.0.0" - knuth-shuffle-seeded: "npm:^1.0.6" - lodash.merge: "npm:^4.6.2" - lodash.mergewith: "npm:^4.6.2" - mz: "npm:^2.7.0" - progress: "npm:^2.0.3" - resolve-pkg: "npm:^2.0.0" - semver: "npm:7.3.7" - stack-chain: "npm:^2.0.0" - string-argv: "npm:^0.3.1" - strip-ansi: "npm:6.0.1" - supports-color: "npm:^8.1.1" - tmp: "npm:^0.2.1" - util-arity: "npm:^1.1.0" - verror: "npm:^1.10.0" - yup: "npm:^0.32.11" - bin: - cucumber-js: bin/cucumber.js - checksum: 10c0/8a8959ea411281886e976d4ec601121078f3440ceb9eb7fa94357f8215e42be8f404a7e6131b4f09cda1c5b7c863bb3dac978e0e4a4d2a58baa4bc54ac204a67 - languageName: node - linkType: hard - -"@cucumber/gherkin-streams@npm:5.0.1": - version: 5.0.1 - resolution: "@cucumber/gherkin-streams@npm:5.0.1" - dependencies: - commander: "npm:9.1.0" - source-map-support: "npm:0.5.21" - peerDependencies: - "@cucumber/gherkin": ">=22.0.0" - "@cucumber/message-streams": ">=4.0.0" - "@cucumber/messages": ">=17.1.1" - bin: - gherkin-javascript: bin/gherkin - checksum: 10c0/37898fa97e73f9d6ca4da9a1eb9c4b147c1d40ceb9882cc4e608ecb5c64c133d36452bbcb17474b918744d4d579194197cf79dede06a84803c8873c64d92d64b - languageName: node - linkType: hard - -"@cucumber/gherkin-utils@npm:8.0.0": - version: 8.0.0 - resolution: "@cucumber/gherkin-utils@npm:8.0.0" - dependencies: - "@cucumber/messages": "npm:^19.0.0" - "@teppeis/multimaps": "npm:2.0.0" - commander: "npm:9.3.0" - bin: - gherkin-utils: bin/gherkin-utils - checksum: 10c0/e771bb5fbdc641ebd87aa92fab1e625a072b8351b799d079d99c22c9bff8ade0cdbf829e93345d2140a682fa75a212abe8c9679d3dfe9e4a1f395199cba541f1 - languageName: node - linkType: hard - -"@cucumber/gherkin@npm:24.0.0": - version: 24.0.0 - resolution: "@cucumber/gherkin@npm:24.0.0" - dependencies: - "@cucumber/messages": "npm:^19.0.0" - checksum: 10c0/7e9855518f8e1255dc38da313119f841c9cb66a383de0310c3b53ebf4cafb2988ac978f6906a3def5c7309e1f4c8985edf713551b017656f93334d2d7dac4fdc - languageName: node - linkType: hard - -"@cucumber/html-formatter@npm:20.0.0": - version: 20.0.0 - resolution: "@cucumber/html-formatter@npm:20.0.0" - peerDependencies: - "@cucumber/messages": ">=18" - checksum: 10c0/c13b4d387a751015ecfb0826545dd6c8bafa3b16fedde28028ff3a09ad59e1f5d677ab54b6590681b97209060bcb453302c8737518dea312fc9e9a5856c7ab60 - languageName: node - linkType: hard - -"@cucumber/message-streams@npm:4.0.1": - version: 4.0.1 - resolution: "@cucumber/message-streams@npm:4.0.1" - peerDependencies: - "@cucumber/messages": ">=17.1.1" - checksum: 10c0/521b68b4a8c00fbdc950f80c057537d1fed9ca532c3d2d3b03b72051a410ee1530e2a5a4f0207086068a0250d9056e23b6c6cd0322b6fd2ec1a520868b696efa - languageName: node - linkType: hard - -"@cucumber/messages@npm:19.1.2": - version: 19.1.2 - resolution: "@cucumber/messages@npm:19.1.2" - dependencies: - "@types/uuid": "npm:8.3.4" - class-transformer: "npm:0.5.1" - reflect-metadata: "npm:0.1.13" - uuid: "npm:8.3.2" - checksum: 10c0/70f0d75e2e02eb181a4cdd8bc96dec614520e97a8e72c8e67581865a3134694e782a763f33cef18e0edadc222b6885aecbfb5426430255bb356f03d6e0d2704c - languageName: node - linkType: hard - -"@cucumber/messages@npm:^19.0.0": - version: 19.1.4 - resolution: "@cucumber/messages@npm:19.1.4" - dependencies: - "@types/uuid": "npm:8.3.4" - class-transformer: "npm:0.5.1" - reflect-metadata: "npm:0.1.13" - uuid: "npm:9.0.0" - checksum: 10c0/08aa0315c5c3e31dcceffb51eda19aaf949f95980bfbe37d64f23f0f685f4aa6ebf7c10c835ef7c9c73acc03e0d0a7011b2253059f796f04ac10be6f57730922 - languageName: node - linkType: hard - -"@cucumber/pretty-formatter@npm:^1.0.0": - version: 1.0.1 - resolution: "@cucumber/pretty-formatter@npm:1.0.1" - dependencies: - ansi-styles: "npm:^5.0.0" - cli-table3: "npm:^0.6.0" - figures: "npm:^3.2.0" - ts-dedent: "npm:^2.0.0" - peerDependencies: - "@cucumber/cucumber": ">=7.0.0" - "@cucumber/messages": "*" - checksum: 10c0/16ac0174bdad47718296c241d20e3ac6b305809675da7c64df8f15542a66be7603dad73a37bbb850241d51da8bbba61e461b861c7e41c0dbbd64684e93a8c265 - languageName: node - linkType: hard - -"@cucumber/tag-expressions@npm:4.1.0": - version: 4.1.0 - resolution: "@cucumber/tag-expressions@npm:4.1.0" - checksum: 10c0/fd66337e5a8b20dc5dbd2ad15de42729214e3a2db346e2598f1d1946f9b602d9cc84b2f7cb76af7e48cf20a5afa78db1dfa3565784209c42fb787ebacdbe1ac8 - languageName: node - linkType: hard - "@discoveryjs/json-ext@npm:^0.5.0": version: 0.5.7 resolution: "@discoveryjs/json-ext@npm:0.5.7" @@ -29396,13 +29223,6 @@ __metadata: languageName: node linkType: hard -"@teppeis/multimaps@npm:2.0.0": - version: 2.0.0 - resolution: "@teppeis/multimaps@npm:2.0.0" - checksum: 10c0/4ea5d469e0be673e464deb1191bcfd4ffd0dc1cf83456f26b4971ec2f14f39a6062a6ec2500f402ae6c4d4546c0a010d3807d4d397943f8f40f43e359d7364c3 - languageName: node - linkType: hard - "@tootallnate/once@npm:2": version: 2.0.0 resolution: "@tootallnate/once@npm:2.0.0" @@ -29744,13 +29564,6 @@ __metadata: languageName: node linkType: hard -"@types/uuid@npm:8.3.4": - version: 8.3.4 - resolution: "@types/uuid@npm:8.3.4" - checksum: 10c0/b9ac98f82fcf35962317ef7dc44d9ac9e0f6fdb68121d384c88fe12ea318487d5585d3480fa003cf28be86a3bbe213ca688ba786601dce4a97724765eb5b1cf2 - languageName: node - linkType: hard - "@types/whatwg-mimetype@npm:^3.0.2": version: 3.0.2 resolution: "@types/whatwg-mimetype@npm:3.0.2" @@ -30804,13 +30617,6 @@ __metadata: languageName: node linkType: hard -"ansi-regex@npm:^4.1.0": - version: 4.1.1 - resolution: "ansi-regex@npm:4.1.1" - checksum: 10c0/d36d34234d077e8770169d980fed7b2f3724bfa2a01da150ccd75ef9707c80e883d27cdf7a0eac2f145ac1d10a785a8a855cffd05b85f778629a0db62e7033da - languageName: node - linkType: hard - "ansi-regex@npm:^5.0.1": version: 5.0.1 resolution: "ansi-regex@npm:5.0.1" @@ -30848,13 +30654,6 @@ __metadata: languageName: node linkType: hard -"any-promise@npm:^1.0.0": - version: 1.3.0 - resolution: "any-promise@npm:1.3.0" - checksum: 10c0/60f0298ed34c74fef50daab88e8dab786036ed5a7fad02e012ab57e376e0a0b4b29e83b95ea9b5e7d89df762f5f25119b83e00706ecaccb22cfbacee98d74889 - languageName: node - linkType: hard - "anymatch@npm:^3.0.3, anymatch@npm:^3.1.1, anymatch@npm:^3.1.3": version: 3.1.3 resolution: "anymatch@npm:3.1.3" @@ -30977,17 +30776,6 @@ __metadata: languageName: node linkType: hard -"assertion-error-formatter@npm:^3.0.0": - version: 3.0.0 - resolution: "assertion-error-formatter@npm:3.0.0" - dependencies: - diff: "npm:^4.0.1" - pad-right: "npm:^0.2.2" - repeat-string: "npm:^1.6.1" - checksum: 10c0/ea2741cfe9272b1efdcc9589c572a6880a32b9efcedc7171dbb0790d59aead8e1553b1edd4c78b65267a301efd2bc5aa75ef0f3cdc2394afb32ede4ea4cc6b64 - languageName: node - linkType: hard - "assertion-error@npm:^2.0.1": version: 2.0.1 resolution: "assertion-error@npm:2.0.1" @@ -31075,8 +30863,6 @@ __metadata: dependencies: "@commitlint/cli": "npm:17.0.2" "@commitlint/config-conventional": "npm:17.0.2" - "@cucumber/cucumber": "npm:8.5.3" - "@cucumber/pretty-formatter": "npm:^1.0.0" "@fastify/formbody": "npm:^7.4.0" "@microsoft/api-extractor": "npm:7.52.7" "@mixer/parallel-prettier": "npm:2.0.3" @@ -31663,17 +31449,6 @@ __metadata: languageName: node linkType: hard -"capital-case@npm:^1.0.4": - version: 1.0.4 - resolution: "capital-case@npm:1.0.4" - dependencies: - no-case: "npm:^3.0.4" - tslib: "npm:^2.0.3" - upper-case-first: "npm:^2.0.2" - checksum: 10c0/6a034af73401f6e55d91ea35c190bbf8bda21714d4ea8bb8f1799311d123410a80f0875db4e3236dc3f97d74231ff4bf1c8783f2be13d7733c7d990c57387281 - languageName: node - linkType: hard - "capture-exit@npm:^2.0.0": version: 2.0.0 resolution: "capture-exit@npm:2.0.0" @@ -31790,13 +31565,6 @@ __metadata: languageName: node linkType: hard -"class-transformer@npm:0.5.1": - version: 0.5.1 - resolution: "class-transformer@npm:0.5.1" - checksum: 10c0/19809914e51c6db42c036166839906420bb60367df14e15f49c45c8c1231bf25ae661ebe94736ee29cc688b77101ef851a8acca299375cc52fc141b64acde18a - languageName: node - linkType: hard - "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" @@ -31827,32 +31595,6 @@ __metadata: languageName: node linkType: hard -"cli-table3@npm:0.6.2": - version: 0.6.2 - resolution: "cli-table3@npm:0.6.2" - dependencies: - "@colors/colors": "npm:1.5.0" - string-width: "npm:^4.2.0" - dependenciesMeta: - "@colors/colors": - optional: true - checksum: 10c0/aaa87929d86ba36e651e0280ab34cc28660e13da9dd2b6f8aa36e800c40e331c32bff53597cb9126e8a2e88e7a9025aff9c240350fe69876207d51ba452ef5e0 - languageName: node - linkType: hard - -"cli-table3@npm:^0.6.0": - version: 0.6.5 - resolution: "cli-table3@npm:0.6.5" - dependencies: - "@colors/colors": "npm:1.5.0" - string-width: "npm:^4.2.0" - dependenciesMeta: - "@colors/colors": - optional: true - checksum: 10c0/d7cc9ed12212ae68241cc7a3133c52b844113b17856e11f4f81308acc3febcea7cc9fd298e70933e294dd642866b29fd5d113c2c098948701d0c35f09455de78 - languageName: node - linkType: hard - "cli-truncate@npm:^2.1.0": version: 2.1.0 resolution: "cli-truncate@npm:2.1.0" @@ -31995,20 +31737,6 @@ __metadata: languageName: node linkType: hard -"commander@npm:9.1.0": - version: 9.1.0 - resolution: "commander@npm:9.1.0" - checksum: 10c0/401daebdfa3cab85b62090a88ed6b9fb4519163afb9247336010e4346970597566c07a832bb84f5c4af68d256b90d01ed7f6984366e6d232d356c533526019b5 - languageName: node - linkType: hard - -"commander@npm:9.3.0": - version: 9.3.0 - resolution: "commander@npm:9.3.0" - checksum: 10c0/4cf2f3a75358e620c3bfb515c5306b3be083463c752504788266a7ff0ed862c0fe3bf7f700154b50546c5c3eca0195f9ca99020184ff6f6128ae7ea87f24b5ba - languageName: node - linkType: hard - "commander@npm:^14.0.0": version: 14.0.2 resolution: "commander@npm:14.0.2" @@ -32037,13 +31765,6 @@ __metadata: languageName: node linkType: hard -"commander@npm:^9.0.0": - version: 9.5.0 - resolution: "commander@npm:9.5.0" - checksum: 10c0/5f7784fbda2aaec39e89eb46f06a999e00224b3763dc65976e05929ec486e174fe9aac2655f03ba6a5e83875bd173be5283dc19309b7c65954701c02025b3c1d - languageName: node - linkType: hard - "commist@npm:^1.0.0": version: 1.1.0 resolution: "commist@npm:1.1.0" @@ -32461,16 +32182,6 @@ __metadata: languageName: node linkType: hard -"d@npm:1, d@npm:^1.0.1, d@npm:^1.0.2": - version: 1.0.2 - resolution: "d@npm:1.0.2" - dependencies: - es5-ext: "npm:^0.10.64" - type: "npm:^2.7.2" - checksum: 10c0/3e6ede10cd3b77586c47da48423b62bed161bf1a48bdbcc94d87263522e22f5dfb0e678a6dba5323fdc14c5d8612b7f7eb9e7d9e37b2e2d67a7bf9f116dabe5a - languageName: node - linkType: hard - "dargs@npm:^7.0.0": version: 7.0.0 resolution: "dargs@npm:7.0.0" @@ -32817,23 +32528,6 @@ __metadata: languageName: node linkType: hard -"duration@npm:^0.2.2": - version: 0.2.2 - resolution: "duration@npm:0.2.2" - dependencies: - d: "npm:1" - es5-ext: "npm:~0.10.46" - checksum: 10c0/06591c3493dfed317a366c852d3d27a65dc9c6c2abe4cac16104f4cbe3fd697feef3c1cedd6ce9b5e03d273dd78489a3d77256a80c49cd5c2b31174ef41827a8 - languageName: node - linkType: hard - -"durations@npm:^3.4.2": - version: 3.4.2 - resolution: "durations@npm:3.4.2" - checksum: 10c0/fbf4466d162ecbe8833a809c6758b021c8864ec3394f4e05bb79546c7597bbec861d17e63e95c467fe1656d36f79bae5b80f9427679b32ef92dbccb10d02db39 - languageName: node - linkType: hard - "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -33053,29 +32747,6 @@ __metadata: languageName: node linkType: hard -"es5-ext@npm:^0.10.35, es5-ext@npm:^0.10.62, es5-ext@npm:^0.10.64, es5-ext@npm:~0.10.14, es5-ext@npm:~0.10.46": - version: 0.10.64 - resolution: "es5-ext@npm:0.10.64" - dependencies: - es6-iterator: "npm:^2.0.3" - es6-symbol: "npm:^3.1.3" - esniff: "npm:^2.0.1" - next-tick: "npm:^1.1.0" - checksum: 10c0/4459b6ae216f3c615db086e02437bdfde851515a101577fd61b19f9b3c1ad924bab4d197981eb7f0ccb915f643f2fc10ff76b97a680e96cbb572d15a27acd9a3 - languageName: node - linkType: hard - -"es6-iterator@npm:^2.0.3": - version: 2.0.3 - resolution: "es6-iterator@npm:2.0.3" - dependencies: - d: "npm:1" - es5-ext: "npm:^0.10.35" - es6-symbol: "npm:^3.1.1" - checksum: 10c0/91f20b799dba28fb05bf623c31857fc1524a0f1c444903beccaf8929ad196c8c9ded233e5ac7214fc63a92b3f25b64b7f2737fcca8b1f92d2d96cf3ac902f5d8 - languageName: node - linkType: hard - "es6-promise@npm:^4.0.3": version: 4.2.8 resolution: "es6-promise@npm:4.2.8" @@ -33092,16 +32763,6 @@ __metadata: languageName: node linkType: hard -"es6-symbol@npm:^3.1.1, es6-symbol@npm:^3.1.3": - version: 3.1.4 - resolution: "es6-symbol@npm:3.1.4" - dependencies: - d: "npm:^1.0.2" - ext: "npm:^1.7.0" - checksum: 10c0/777bf3388db5d7919e09a0fd175aa5b8a62385b17cb2227b7a137680cba62b4d9f6193319a102642aa23d5840d38a62e4784f19cfa5be4a2210a3f0e9b23d15d - languageName: node - linkType: hard - "esbuild@npm:0.25.0": version: 0.25.0 resolution: "esbuild@npm:0.25.0" @@ -33528,18 +33189,6 @@ __metadata: languageName: node linkType: hard -"esniff@npm:^2.0.1": - version: 2.0.1 - resolution: "esniff@npm:2.0.1" - dependencies: - d: "npm:^1.0.1" - es5-ext: "npm:^0.10.62" - event-emitter: "npm:^0.3.5" - type: "npm:^2.7.2" - checksum: 10c0/7efd8d44ac20e5db8cb0ca77eb65eca60628b2d0f3a1030bcb05e71cc40e6e2935c47b87dba3c733db12925aa5b897f8e0e7a567a2c274206f184da676ea2e65 - languageName: node - linkType: hard - "espree@npm:^9.5.0, espree@npm:^9.6.0": version: 9.6.1 resolution: "espree@npm:9.6.1" @@ -33641,16 +33290,6 @@ __metadata: languageName: node linkType: hard -"event-emitter@npm:^0.3.5": - version: 0.3.5 - resolution: "event-emitter@npm:0.3.5" - dependencies: - d: "npm:1" - es5-ext: "npm:~0.10.14" - checksum: 10c0/75082fa8ffb3929766d0f0a063bfd6046bd2a80bea2666ebaa0cfd6f4a9116be6647c15667bea77222afc12f5b4071b68d393cf39fdaa0e8e81eda006160aff0 - languageName: node - linkType: hard - "event-target-shim@npm:^5.0.0": version: 5.0.1 resolution: "event-target-shim@npm:5.0.1" @@ -33814,15 +33453,6 @@ __metadata: languageName: node linkType: hard -"ext@npm:^1.7.0": - version: 1.7.0 - resolution: "ext@npm:1.7.0" - dependencies: - type: "npm:^2.7.2" - checksum: 10c0/a8e5f34e12214e9eee3a4af3b5c9d05ba048f28996450975b369fc86e5d0ef13b6df0615f892f5396a9c65d616213c25ec5b0ad17ef42eac4a500512a19da6c7 - languageName: node - linkType: hard - "extend@npm:^3.0.2, extend@npm:~3.0.2": version: 3.0.2 resolution: "extend@npm:3.0.2" @@ -34068,7 +33698,7 @@ __metadata: languageName: node linkType: hard -"figures@npm:3.2.0, figures@npm:^3.0.0, figures@npm:^3.2.0": +"figures@npm:3.2.0, figures@npm:^3.0.0": version: 3.2.0 resolution: "figures@npm:3.2.0" dependencies: @@ -34714,15 +34344,6 @@ __metadata: languageName: node linkType: hard -"global-dirs@npm:^3.0.0": - version: 3.0.1 - resolution: "global-dirs@npm:3.0.1" - dependencies: - ini: "npm:2.0.0" - checksum: 10c0/ef65e2241a47ff978f7006a641302bc7f4c03dfb98783d42bf7224c136e3a06df046e70ee3a010cf30214114755e46c9eb5eb1513838812fbbe0d92b14c25080 - languageName: node - linkType: hard - "globals@npm:^13.19.0": version: 13.24.0 resolution: "globals@npm:13.24.0" @@ -34849,15 +34470,6 @@ __metadata: languageName: node linkType: hard -"has-ansi@npm:^4.0.1": - version: 4.0.1 - resolution: "has-ansi@npm:4.0.1" - dependencies: - ansi-regex: "npm:^4.1.0" - checksum: 10c0/fa711146258487d0f7c5bb2d97dbb16ab9a78a314238aaa017d7fbab4ebf555ac3465ebec5875eb378138289467e0612d8f5606bc2273149b4361e4befebbbcf - languageName: node - linkType: hard - "has-flag@npm:^4.0.0": version: 4.0.0 resolution: "has-flag@npm:4.0.0" @@ -35188,13 +34800,6 @@ __metadata: languageName: node linkType: hard -"ini@npm:2.0.0": - version: 2.0.0 - resolution: "ini@npm:2.0.0" - checksum: 10c0/2e0c8f386369139029da87819438b20a1ff3fe58372d93fb1a86e9d9344125ace3a806b8ec4eb160a46e64cbc422fe68251869441676af49b7fc441af2389c25 - languageName: node - linkType: hard - "ini@npm:^1.3.2, ini@npm:^1.3.4": version: 1.3.8 resolution: "ini@npm:1.3.8" @@ -35344,16 +34949,6 @@ __metadata: languageName: node linkType: hard -"is-installed-globally@npm:^0.4.0": - version: 0.4.0 - resolution: "is-installed-globally@npm:0.4.0" - dependencies: - global-dirs: "npm:^3.0.0" - is-path-inside: "npm:^3.0.2" - checksum: 10c0/f3e6220ee5824b845c9ed0d4b42c24272701f1f9926936e30c0e676254ca5b34d1b92c6205cae11b283776f9529212c0cdabb20ec280a6451677d6493ca9c22d - languageName: node - linkType: hard - "is-interactive@npm:^1.0.0": version: 1.0.0 resolution: "is-interactive@npm:1.0.0" @@ -35403,7 +34998,7 @@ __metadata: languageName: node linkType: hard -"is-path-inside@npm:^3.0.2, is-path-inside@npm:^3.0.3": +"is-path-inside@npm:^3.0.3": version: 3.0.3 resolution: "is-path-inside@npm:3.0.3" checksum: 10c0/cf7d4ac35fb96bab6a1d2c3598fe5ebb29aafb52c0aaa482b5a3ed9d8ba3edc11631e3ec2637660c44b3ce0e61a08d54946e8af30dec0b60a7c27296c68ffd05 @@ -36878,15 +36473,6 @@ __metadata: languageName: node linkType: hard -"knuth-shuffle-seeded@npm:^1.0.6": - version: 1.0.6 - resolution: "knuth-shuffle-seeded@npm:1.0.6" - dependencies: - seed-random: "npm:~2.2.0" - checksum: 10c0/c8a3085fec79a3bac24bcccd0be7bf757f881e023d587ce858afc684c1a6c979ae6d9493e5efc6dc331527a8af0e4fe512d66e34ac39e79f45ae967ac8a60d6e - languageName: node - linkType: hard - "lerna@npm:5.5.2": version: 5.5.2 resolution: "lerna@npm:5.5.2" @@ -37238,15 +36824,6 @@ __metadata: languageName: node linkType: hard -"lower-case@npm:^2.0.2": - version: 2.0.2 - resolution: "lower-case@npm:2.0.2" - dependencies: - tslib: "npm:^2.0.3" - checksum: 10c0/3d925e090315cf7dc1caa358e0477e186ffa23947740e4314a7429b6e62d72742e0bbe7536a5ae56d19d7618ce998aba05caca53c2902bd5742fdca5fc57fd7b - languageName: node - linkType: hard - "lru-cache@npm:7.18.3, lru-cache@npm:^7.4.4, lru-cache@npm:^7.5.1, lru-cache@npm:^7.7.1": version: 7.18.3 resolution: "lru-cache@npm:7.18.3" @@ -37883,17 +37460,6 @@ __metadata: languageName: node linkType: hard -"mz@npm:^2.7.0": - version: 2.7.0 - resolution: "mz@npm:2.7.0" - dependencies: - any-promise: "npm:^1.0.0" - object-assign: "npm:^4.0.1" - thenify-all: "npm:^1.0.0" - checksum: 10c0/103114e93f87362f0b56ab5b2e7245051ad0276b646e3902c98397d18bb8f4a77f2ea4a2c9d3ad516034ea3a56553b60d3f5f78220001ca4c404bd711bd0af39 - languageName: node - linkType: hard - "nanoclone@npm:^0.2.1": version: 0.2.1 resolution: "nanoclone@npm:0.2.1" @@ -37970,23 +37536,6 @@ __metadata: languageName: node linkType: hard -"next-tick@npm:^1.1.0": - version: 1.1.0 - resolution: "next-tick@npm:1.1.0" - checksum: 10c0/3ba80dd805fcb336b4f52e010992f3e6175869c8d88bf4ff0a81d5d66e6049f89993463b28211613e58a6b7fe93ff5ccbba0da18d4fa574b96289e8f0b577f28 - languageName: node - linkType: hard - -"no-case@npm:^3.0.4": - version: 3.0.4 - resolution: "no-case@npm:3.0.4" - dependencies: - lower-case: "npm:^2.0.2" - tslib: "npm:^2.0.3" - checksum: 10c0/8ef545f0b3f8677c848f86ecbd42ca0ff3cd9dd71c158527b344c69ba14710d816d8489c746b6ca225e7b615108938a0bda0a54706f8c255933703ac1cf8e703 - languageName: node - linkType: hard - "node-addon-api@npm:^3.2.1": version: 3.2.1 resolution: "node-addon-api@npm:3.2.1" @@ -38390,7 +37939,7 @@ __metadata: languageName: node linkType: hard -"object-assign@npm:^4, object-assign@npm:^4.0.1": +"object-assign@npm:^4": version: 4.1.1 resolution: "object-assign@npm:4.1.1" checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414 @@ -38697,15 +38246,6 @@ __metadata: languageName: node linkType: hard -"pad-right@npm:^0.2.2": - version: 0.2.2 - resolution: "pad-right@npm:0.2.2" - dependencies: - repeat-string: "npm:^1.5.2" - checksum: 10c0/fa8752633a616d1310550df4bf602d4f3bc58753033cfdd45a381fbf0c39c7ddeb577d37f9dd3746cbc85f9fd957ca9dce346f39e9f18e199aaa3d0dbb11595a - languageName: node - linkType: hard - "parent-module@npm:^1.0.0": version: 1.0.1 resolution: "parent-module@npm:1.0.1" @@ -39172,13 +38712,6 @@ __metadata: languageName: node linkType: hard -"progress@npm:^2.0.3": - version: 2.0.3 - resolution: "progress@npm:2.0.3" - checksum: 10c0/1697e07cb1068055dbe9fe858d242368ff5d2073639e652b75a7eb1f2a1a8d4afd404d719de23c7b48481a6aa0040686310e2dac2f53d776daa2176d3f96369c - languageName: node - linkType: hard - "promise-all-reject-late@npm:^1.0.0": version: 1.0.1 resolution: "promise-all-reject-late@npm:1.0.1" @@ -39591,31 +39124,6 @@ __metadata: languageName: node linkType: hard -"reflect-metadata@npm:0.1.13": - version: 0.1.13 - resolution: "reflect-metadata@npm:0.1.13" - checksum: 10c0/728bff0b376b05639fd11ed80c648b61f7fe653c5b506d7ca118e58b6752b9b00810fe0c86227ecf02bd88da6251ab3eb19fd403aaf2e9ff5ef36a2fda643026 - languageName: node - linkType: hard - -"regexp-match-indices@npm:1.0.2": - version: 1.0.2 - resolution: "regexp-match-indices@npm:1.0.2" - dependencies: - regexp-tree: "npm:^0.1.11" - checksum: 10c0/35e8af9844a4d08f54000766a7f364579c2082080b6f0f6edb9af9faab0452a83e68ef71304e3b2d12ff6d71a615d30b43de60cafeabbce3e1fa95c56383d147 - languageName: node - linkType: hard - -"regexp-tree@npm:^0.1.11": - version: 0.1.27 - resolution: "regexp-tree@npm:0.1.27" - bin: - regexp-tree: bin/regexp-tree - checksum: 10c0/f636f44b4a0d93d7d6926585ecd81f63e4ce2ac895bc417b2ead0874cd36b337dcc3d0fedc63f69bf5aaeaa4340f36ca7e750c9687cceaf8087374e5284e843c - languageName: node - linkType: hard - "reinterval@npm:^1.1.0": version: 1.1.0 resolution: "reinterval@npm:1.1.0" @@ -39630,13 +39138,6 @@ __metadata: languageName: node linkType: hard -"repeat-string@npm:^1.5.2, repeat-string@npm:^1.6.1": - version: 1.6.1 - resolution: "repeat-string@npm:1.6.1" - checksum: 10c0/87fa21bfdb2fbdedc44b9a5b118b7c1239bdd2c2c1e42742ef9119b7d412a5137a1d23f1a83dc6bb686f4f27429ac6f542e3d923090b44181bafa41e8ac0174d - languageName: node - linkType: hard - "request@npm:2.88.2": version: 2.88.2 resolution: "request@npm:2.88.2" @@ -39718,15 +39219,6 @@ __metadata: languageName: node linkType: hard -"resolve-pkg@npm:^2.0.0": - version: 2.0.0 - resolution: "resolve-pkg@npm:2.0.0" - dependencies: - resolve-from: "npm:^5.0.0" - checksum: 10c0/c48af43563ae10fef4a20217808d7cc1de450837f5522963b559975d7b0bb28b7eee6f98bd815a93ebd083cc56b3139c520a22c066ee7abea73b819ea2764713 - languageName: node - linkType: hard - "resolve.exports@npm:^2.0.0": version: 2.0.3 resolution: "resolve.exports@npm:2.0.3" @@ -40037,13 +39529,6 @@ __metadata: languageName: node linkType: hard -"seed-random@npm:~2.2.0": - version: 2.2.0 - resolution: "seed-random@npm:2.2.0" - checksum: 10c0/5d48dedf312e8075faa899664ec5867e3b088a11d0e955d7c6bcfffcd7fc6de5dbb51c41c24ef48060ee6a9592cad607e5c44306b4fd4828667451afe16b09a5 - languageName: node - linkType: hard - "semver-compare@npm:^1.0.0": version: 1.0.0 resolution: "semver-compare@npm:1.0.0" @@ -40067,17 +39552,6 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.3.7": - version: 7.3.7 - resolution: "semver@npm:7.3.7" - dependencies: - lru-cache: "npm:^6.0.0" - bin: - semver: bin/semver.js - checksum: 10c0/cffd30102de68a9f8cac9ef57b43c2173dc999da4fc5189872b421f9c9e2660f70243b8e964781ac6dc48ba2542647bb672beeb4d756c89c4a9e05e1144fa40a - languageName: node - linkType: hard - "semver@npm:7.5.0": version: 7.5.0 resolution: "semver@npm:7.5.0" @@ -40443,7 +39917,7 @@ __metadata: languageName: node linkType: hard -"source-map-support@npm:0.5.21, source-map-support@npm:~0.5.20": +"source-map-support@npm:~0.5.20": version: 0.5.21 resolution: "source-map-support@npm:0.5.21" dependencies: @@ -40581,13 +40055,6 @@ __metadata: languageName: node linkType: hard -"stack-chain@npm:^2.0.0": - version: 2.0.0 - resolution: "stack-chain@npm:2.0.0" - checksum: 10c0/60f314ecd9614ab34512d15fdf4d8eec8470437997fc81774d4a9ac90060e5468c24999cc8ec185ae6c369ff732665e16f8f4eaa3e9ebccdc7c32bc2b974d949 - languageName: node - linkType: hard - "stack-utils@npm:^2.0.3, stack-utils@npm:^2.0.6": version: 2.0.6 resolution: "stack-utils@npm:2.0.6" @@ -40651,7 +40118,7 @@ __metadata: languageName: node linkType: hard -"string-argv@npm:^0.3.1, string-argv@npm:~0.3.1": +"string-argv@npm:~0.3.1": version: 0.3.2 resolution: "string-argv@npm:0.3.2" checksum: 10c0/75c02a83759ad1722e040b86823909d9a2fc75d15dd71ec4b537c3560746e33b5f5a07f7332d1e3f88319909f82190843aa2f0a0d8c8d591ec08e93d5b8dec82 @@ -40719,7 +40186,7 @@ __metadata: languageName: node linkType: hard -"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": version: 6.0.1 resolution: "strip-ansi@npm:6.0.1" dependencies: @@ -40952,24 +40419,6 @@ __metadata: languageName: node linkType: hard -"thenify-all@npm:^1.0.0": - version: 1.6.0 - resolution: "thenify-all@npm:1.6.0" - dependencies: - thenify: "npm:>= 3.1.0 < 4" - checksum: 10c0/9b896a22735e8122754fe70f1d65f7ee691c1d70b1f116fda04fea103d0f9b356e3676cb789506e3909ae0486a79a476e4914b0f92472c2e093d206aed4b7d6b - languageName: node - linkType: hard - -"thenify@npm:>= 3.1.0 < 4": - version: 3.3.1 - resolution: "thenify@npm:3.3.1" - dependencies: - any-promise: "npm:^1.0.0" - checksum: 10c0/f375aeb2b05c100a456a30bc3ed07ef03a39cbdefe02e0403fb714b8c7e57eeaad1a2f5c4ecfb9ce554ce3db9c2b024eba144843cd9e344566d9fcee73b04767 - languageName: node - linkType: hard - "thread-stream@npm:^0.15.1": version: 0.15.2 resolution: "thread-stream@npm:0.15.2" @@ -41069,7 +40518,7 @@ __metadata: languageName: node linkType: hard -"tmp@npm:^0.2.1, tmp@npm:~0.2.1": +"tmp@npm:~0.2.1": version: 0.2.5 resolution: "tmp@npm:0.2.5" checksum: 10c0/cee5bb7d674bb4ba3ab3f3841c2ca7e46daeb2109eec395c1ec7329a91d52fcb21032b79ac25161a37b2565c4858fefab927af9735926a113ef7bac9091a6e0e @@ -41163,13 +40612,6 @@ __metadata: languageName: node linkType: hard -"ts-dedent@npm:^2.0.0": - version: 2.2.0 - resolution: "ts-dedent@npm:2.2.0" - checksum: 10c0/175adea838468cc2ff7d5e97f970dcb798bbcb623f29c6088cb21aa2880d207c5784be81ab1741f56b9ac37840cbaba0c0d79f7f8b67ffe61c02634cafa5c303 - languageName: node - linkType: hard - "ts-jest@npm:29.1.1": version: 29.1.1 resolution: "ts-jest@npm:29.1.1" @@ -41274,7 +40716,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.6.2": +"tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.6.2": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 @@ -41477,13 +40919,6 @@ __metadata: languageName: node linkType: hard -"type@npm:^2.7.2": - version: 2.7.3 - resolution: "type@npm:2.7.3" - checksum: 10c0/dec6902c2c42fcb86e3adf8cdabdf80e5ef9de280872b5fd547351e9cca2fe58dd2aa6d2547626ddff174145db272f62d95c7aa7038e27c11315657d781a688d - languageName: node - linkType: hard - "typedarray-to-buffer@npm:^3.1.5": version: 3.1.5 resolution: "typedarray-to-buffer@npm:3.1.5" @@ -41719,15 +41154,6 @@ __metadata: languageName: node linkType: hard -"upper-case-first@npm:^2.0.2": - version: 2.0.2 - resolution: "upper-case-first@npm:2.0.2" - dependencies: - tslib: "npm:^2.0.3" - checksum: 10c0/ccad6a0b143310ebfba2b5841f30bef71246297385f1329c022c902b2b5fc5aee009faf1ac9da5ab3ba7f615b88f5dc1cd80461b18a8f38cb1d4c3eb92538ea9 - languageName: node - linkType: hard - "uri-js@npm:^4.2.2, uri-js@npm:^4.4.1": version: 4.4.1 resolution: "uri-js@npm:4.4.1" @@ -41737,13 +41163,6 @@ __metadata: languageName: node linkType: hard -"util-arity@npm:^1.1.0": - version: 1.1.0 - resolution: "util-arity@npm:1.1.0" - checksum: 10c0/eed63ffd055fcbbcfce9dd93c10cc94472e76d8d4e4d9c2ba9f08668af84aaa7efe3396123045660e6449f61adf83be8b455e20b231305dae9cfa3c599b69e0d - languageName: node - linkType: hard - "util-deprecate@npm:^1.0.1, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" @@ -41758,24 +41177,6 @@ __metadata: languageName: node linkType: hard -"uuid@npm:8.3.2, uuid@npm:^8.3.2": - version: 8.3.2 - resolution: "uuid@npm:8.3.2" - bin: - uuid: dist/bin/uuid - checksum: 10c0/bcbb807a917d374a49f475fae2e87fdca7da5e5530820ef53f65ba1d12131bd81a92ecf259cc7ce317cbe0f289e7d79fdfebcef9bfa3087c8c8a2fa304c9be54 - languageName: node - linkType: hard - -"uuid@npm:9.0.0": - version: 9.0.0 - resolution: "uuid@npm:9.0.0" - bin: - uuid: dist/bin/uuid - checksum: 10c0/8867e438990d1d33ac61093e2e4e3477a2148b844e4fa9e3c2360fa4399292429c4b6ec64537eb1659c97b2d10db349c673ad58b50e2824a11e0d3630de3c056 - languageName: node - linkType: hard - "uuid@npm:^3.3.2": version: 3.4.0 resolution: "uuid@npm:3.4.0" @@ -41785,6 +41186,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:^8.3.2": + version: 8.3.2 + resolution: "uuid@npm:8.3.2" + bin: + uuid: dist/bin/uuid + checksum: 10c0/bcbb807a917d374a49f475fae2e87fdca7da5e5530820ef53f65ba1d12131bd81a92ecf259cc7ce317cbe0f289e7d79fdfebcef9bfa3087c8c8a2fa304c9be54 + languageName: node + linkType: hard + "v8-compile-cache-lib@npm:^3.0.1": version: 3.0.1 resolution: "v8-compile-cache-lib@npm:3.0.1" @@ -41944,17 +41354,6 @@ __metadata: languageName: node linkType: hard -"verror@npm:^1.10.0": - version: 1.10.1 - resolution: "verror@npm:1.10.1" - dependencies: - assert-plus: "npm:^1.0.0" - core-util-is: "npm:1.0.2" - extsprintf: "npm:^1.2.0" - checksum: 10c0/293fb060a4c9b07965569a0c3e45efa954127818707995a8a4311f691b5d6687be99f972c759838ba6eecae717f9af28e3c49d2afc7bbdf5f0b675238f1426e8 - languageName: node - linkType: hard - "vite-node@npm:3.2.4": version: 3.2.4 resolution: "vite-node@npm:3.2.4" @@ -42600,7 +41999,7 @@ __metadata: languageName: node linkType: hard -"yup@npm:0.32.11, yup@npm:^0.32.11": +"yup@npm:0.32.11": version: 0.32.11 resolution: "yup@npm:0.32.11" dependencies: