Skip to content

Commit

Permalink
test: e2e for non-interactive init/pull in git-cloned project (#11365)
Browse files Browse the repository at this point in the history
  • Loading branch information
edwardfoyle authored Nov 11, 2022
1 parent c4d6dc2 commit 03cee46
Show file tree
Hide file tree
Showing 18 changed files with 386 additions and 160 deletions.
1 change: 1 addition & 0 deletions .eslint-dictionary.json
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@
"uint",
"unauth",
"unlink",
"unstaged",
"updateamplify",
"urls",
"userpool",
Expand Down
1 change: 1 addition & 0 deletions packages/amplify-e2e-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"execa": "^5.1.1",
"fs-extra": "^8.1.0",
"graphql-transformer-core": "^7.6.6",
"ini": "^1.3.5",
"jest-environment-node": "^26.6.2",
"lodash": "^4.17.21",
"node-fetch": "^2.6.7",
Expand Down
46 changes: 8 additions & 38 deletions packages/amplify-e2e-core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/* eslint-disable prefer-arrow/prefer-arrow-functions */
/* eslint-disable func-style */
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable jsdoc/require-jsdoc */
/* eslint-disable import/no-cycle */
import * as os from 'os';
import * as path from 'path';
import * as fs from 'fs-extra';
Expand All @@ -12,12 +17,12 @@ export * from './configure';
export * from './init';
export * from './utils';
export * from './categories';
export * from './utils/sdk-calls';
export * from './export';
export { addFeatureFlag } from './utils/feature-flags';
export * from './cli-version-controller';

declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace NodeJS {
interface Global {
getRandomId: () => string;
Expand All @@ -27,9 +32,6 @@ declare global {

const amplifyTestsDir = 'amplify-e2e-tests';

/**
*
*/
export function getCLIPath(testingWithLatestCodebase = false) {
if (!testingWithLatestCodebase) {
if (process.env.AMPLIFY_PATH && fs.existsSync(process.env.AMPLIFY_PATH)) {
Expand All @@ -43,16 +45,10 @@ export function getCLIPath(testingWithLatestCodebase = false) {
return amplifyScriptPath;
}

/**
*
*/
export function isTestingWithLatestCodebase(scriptRunnerPath) {
return scriptRunnerPath === process.execPath;
}

/**
*
*/
export function getScriptRunnerPath(testingWithLatestCodebase = false) {
if (!testingWithLatestCodebase) {
return process.platform === 'win32' ? 'node.exe' : 'exec';
Expand All @@ -62,9 +58,6 @@ export function getScriptRunnerPath(testingWithLatestCodebase = false) {
return process.execPath;
}

/**
*
*/
export function getNpxPath() {
let npxPath = 'npx';
if (process.platform === 'win32') {
Expand All @@ -73,9 +66,6 @@ export function getNpxPath() {
return npxPath;
}

/**
*
*/
export function getNpmPath() {
let npmPath = 'npm';
if (process.platform === 'win32') {
Expand All @@ -84,33 +74,17 @@ export function getNpmPath() {
return npmPath;
}

/**
*
*/
export function isCI(): boolean {
return !!(process.env.CI && process.env.CIRCLECI);
}

/**
*
*/
export function injectSessionToken(profileName: string) {
const credentialsContents = ini.parse(fs.readFileSync(pathManager.getAWSCredentialsFilePath()).toString());
credentialsContents[profileName] = credentialsContents[profileName] || {};
credentialsContents[profileName].aws_session_token = process.env.AWS_SESSION_TOKEN;
fs.writeFileSync(pathManager.getAWSCredentialsFilePath(), ini.stringify(credentialsContents));
}

/**
*
*/
export function npmInstall(cwd: string) {
spawnSync('npm', ['install'], { cwd });
}

/**
*
*/
export async function installAmplifyCLI(version = 'latest') {
spawnSync('npm', ['install', '-g', `@aws-amplify/cli@${version}`], {
cwd: process.cwd(),
Expand All @@ -122,11 +96,9 @@ export async function installAmplifyCLI(version = 'latest') {
: path.join(os.homedir(), '.npm-global', 'bin', 'amplify');
}

/**
*
*/
export async function createNewProjectDir(
projectName: string,
// eslint-disable-next-line spellcheck/spell-checker
prefix = path.join(fs.realpathSync(os.tmpdir()), amplifyTestsDir),
): Promise<string> {
const currentHash = execSync('git rev-parse --short HEAD', { cwd: __dirname }).toString().trim();
Expand All @@ -141,10 +113,8 @@ export async function createNewProjectDir(
return projectDir;
}

/**
*
*/
export const createTempDir = () => {
// eslint-disable-next-line spellcheck/spell-checker
const osTempDir = fs.realpathSync(os.tmpdir());
const tempProjectDir = path.join(osTempDir, amplifyTestsDir, uuid());

Expand Down
13 changes: 13 additions & 0 deletions packages/amplify-e2e-core/src/init/headless-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Shape of awscloudformation object within `--profile` payload for init/pull
*/
export type AwsProviderConfig = {
configLevel: string,
useProfile: boolean,
profileName: string,
}

/**
* Shape of `--categories` payload for init/pull
*/
export type CategoriesConfig = Record<string, unknown>;
2 changes: 2 additions & 0 deletions packages/amplify-e2e-core/src/init/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/* eslint-disable import/no-cycle */
export * from './amplifyPull';
export * from './amplifyPush';
export * from './deleteProject';
export * from './initProjectHelper';
export * from './pull-headless';
export * from './adminUI';
export * from './overrideStack';
export * from './non-interactive-init';
56 changes: 56 additions & 0 deletions packages/amplify-e2e-core/src/init/non-interactive-init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import execa from 'execa';
// eslint-disable-next-line import/no-cycle
import { getCLIPath, TEST_PROFILE_NAME } from '..';
import { CategoriesConfig, AwsProviderConfig } from './headless-types';

/**
* Executes a non-interactive init to attach a local project to an existing cloud environment
*/
export const nonInteractiveInitAttach = async (
projRoot: string,
amplifyInitConfig: AmplifyInitConfig,
categoriesConfig?: CategoriesConfig,
awsProviderConfig = getAwsProviderConfig(),
): Promise<void> => {
const args = [
'init',
'--yes',
'--amplify',
JSON.stringify(amplifyInitConfig),
'--providers',
JSON.stringify({
awscloudformation: awsProviderConfig,
}),
];
if (categoriesConfig) {
args.push('--categories', JSON.stringify(categoriesConfig));
}
await execa(getCLIPath(), args, { cwd: projRoot });
};

/**
* Returns an AmplifyConfig object with a default editor
*/
export const getAmplifyInitConfig = (projectName: string, envName: string): AmplifyInitConfig => ({
projectName,
envName,
defaultEditor: 'code',
});

/**
* Returns a default AwsProviderConfig
*/
export const getAwsProviderConfig = (): AwsProviderConfig => ({
configLevel: 'project',
useProfile: true,
profileName: TEST_PROFILE_NAME,
});

/**
* Shape of `--amplify` payload for init/pull
*/
export type AmplifyInitConfig = {
projectName: string,
envName: string,
defaultEditor: string,
};
58 changes: 22 additions & 36 deletions packages/amplify-e2e-core/src/init/overrideStack.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,36 @@
/* eslint-disable jsdoc/require-jsdoc */
// eslint-disable-next-line import/no-cycle
import { nspawn as spawn, getCLIPath } from '..';

export function amplifyOverrideRoot(cwd: string, settings: { testingWithLatestCodebase?: boolean }) {
return new Promise((resolve, reject) => {
const args = ['override', 'project'];
export const amplifyOverrideRoot = (cwd: string, settings: { testingWithLatestCodebase?: boolean }): Promise<void> => {
const args = ['override', 'project'];

spawn(getCLIPath(settings.testingWithLatestCodebase), args, { cwd, stripColors: true })
.wait('Do you want to edit override.ts file now?')
.sendNo()
.sendEof()
.run((err: Error) => {
if (!err) {
resolve({});
} else {
reject(err);
}
});
});
}
return spawn(getCLIPath(settings.testingWithLatestCodebase), args, { cwd, stripColors: true })
.wait('Do you want to edit override.ts file now?')
.sendNo()
.sendEof()
.runAsync();
};

export function amplifyOverrideAuth(cwd: string, settings: {}) {
return new Promise((resolve, reject) => {
const args = ['override', 'auth'];
export const amplifyOverrideAuth = (cwd: string): Promise<void> => {
const args = ['override', 'auth'];

spawn(getCLIPath(), args, { cwd, stripColors: true })
.wait('Do you want to edit override.ts file now?')
.sendNo()
.sendEof()
.run((err: Error) => {
if (!err) {
resolve({});
} else {
reject(err);
}
});
});
}
return spawn(getCLIPath(), args, { cwd, stripColors: true })
.wait('Do you want to edit override.ts file now?')
.sendNo()
.sendEof()
.runAsync();
};

export function amplifyOverrideApi(cwd: string, settings: any) {
export const amplifyOverrideApi = (cwd: string): Promise<void> => {
const args = ['override', 'api'];
const chain = spawn(getCLIPath(), args, { cwd, stripColors: true });
chain.wait('Do you want to edit override.ts file now?').sendNo().sendEof();
return chain.runAsync();
}
};

export function buildOverrides(cwd: string, settings: any) {
export const buildOverrides = (cwd: string): Promise<void> => {
const args = ['build'];
const chain = spawn(getCLIPath(), args, { cwd, stripColors: true });
return chain.runAsync();
}
};
Loading

0 comments on commit 03cee46

Please sign in to comment.