Repository: elastic/synthetics (ts)

Issue:
Synthetics init fails because `templates` weren't included in distributable
# Summary

Right now, the `synthetics init` command fails because the `templates` folder is lacking files. If you build the package locally it runs fine because the templates will be copied, but if you use `npx`, for example, you will see the following error:

```
Error: ENOENT: no such file or directory, open '/Users/lucasfcosta/.npm/_npx/XYZ/node_modules/@elastic/synthetics/templates/.gitignore'
```

# How to reproduce

1. Run `npx @elastic/synthetics init my-project`

Pull request:
fix: write .gitnore files for scaffolding
+ fix #509 
+ We update the `.gitignore` contents if the init is called on an existing directory and override it instead of using it from the templates directory. 

Patch:
diff --git a/README.md b/README.md
index 26bb94a..9343fad 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
 # Experimental Synthetics Agent
 
 Synthetic Monitoring with Real Browsers.
-**Please note this is an unsupported experimental project. Expect things to break and change!**
+**Please note this is project is in beta status. Expect things to break and change!**
 
 ## Usage
 
diff --git a/src/generator/index.ts b/src/generator/index.ts
index 602a5c0..7dcd470 100644
--- a/src/generator/index.ts
+++ b/src/generator/index.ts
@@ -59,11 +59,6 @@ export class Generator {
       journeyFile,
       await readFile(join(templateDir, journeyFile), 'utf-8')
     );
-    // Setup gitignore
-    fileMap.set(
-      '.gitignore',
-      await readFile(join(templateDir, '.gitignore'), 'utf-8')
-    );
 
     // Create files
     for (const [relativePath, content] of fileMap) {
@@ -131,6 +126,20 @@ export class Generator {
     );
   }
 
+  async patchGitIgnore() {
+    const gitIgnorePath = join(this.projectDir, '.gitignore');
+    let gitIgnore = '';
+    if (existsSync(gitIgnorePath)) {
+      const contents = await readFile(gitIgnorePath, 'utf-8');
+      gitIgnore += contents.trimEnd() + '\n';
+    }
+    if (!gitIgnore.includes('node_modules')) {
+      gitIgnore += 'node_modules/\n';
+    }
+    gitIgnore += '.synthetics/\n';
+    await writeFile(gitIgnorePath, gitIgnore, 'utf-8');
+  }
+
   banner() {
     stdWrite(
       bold(`
@@ -154,6 +163,7 @@ Visit https://www.elastic.co/guide/en/observability/master/synthetics-journeys.h
     await this.package();
     await this.files();
     await this.patchPkgJSON();
+    await this.patchGitIgnore();
     this.banner();
   }
 }
diff --git a/templates/.gitignore b/templates/.gitignore
deleted file mode 100644
index 36c1c3a..0000000
--- a/templates/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-node_modules
-.synthetics
diff --git a/templates/synthetics.config.ts b/templates/synthetics.config.ts
index 4109f86..93109b1 100644
--- a/templates/synthetics.config.ts
+++ b/templates/synthetics.config.ts
@@ -8,6 +8,10 @@ export default env => {
     playwrightOptions: {
       ignoreHTTPSErrors: false,
     },
+    /**
+     * Configure global monitor settings
+     */
+    monitor: {},
   };
   if (env !== 'development') {
     /**


Test patch:
diff --git a/__tests__/generator/index.test.ts b/__tests__/generator/index.test.ts
index 761a713..b00d6ea 100644
--- a/__tests__/generator/index.test.ts
+++ b/__tests__/generator/index.test.ts
@@ -24,7 +24,7 @@
  */
 
 import { existsSync } from 'fs';
-import { rm } from 'fs/promises';
+import { readFile, rm } from 'fs/promises';
 import { join } from 'path';
 import { CLIMock } from '../utils/test-config';
 
@@ -49,6 +49,15 @@ describe('Generator', () => {
     expect(existsSync(join(scaffoldDir, 'package.json'))).toBeTruthy();
     expect(existsSync(join(scaffoldDir, 'package-lock.json'))).toBeTruthy();
     expect(existsSync(join(scaffoldDir, '.gitignore'))).toBeTruthy();
+
+    // Verify gitignore contents
+    expect(await readFile(join(scaffoldDir, '.gitignore'), 'utf-8'))
+      .toMatchInlineSnapshot(`
+      "node_modules/
+      .synthetics/
+      "
+    `);
+
     expect(
       existsSync(join(scaffoldDir, 'journeys', 'example.journey.ts'))
     ).toBeTruthy();
diff --git a/__tests__/utils/test-config.ts b/__tests__/utils/test-config.ts
index 010e5e1..2e34669 100644
--- a/__tests__/utils/test-config.ts
+++ b/__tests__/utils/test-config.ts
@@ -53,7 +53,7 @@ export class CLIMock {
   private chunks: Array<string> = [];
   private waitForText: string;
   private waitForPromise: () => void;
-  private cliArgs: string[];
+  private cliArgs: string[] = [];
   private stdinStr?: string;
   private stderrStr: string;
   exitCode: Promise<number>;
@@ -61,7 +61,12 @@ export class CLIMock {
   constructor(public debug: boolean = false) {}
 
   args(a: string[]): CLIMock {
-    this.cliArgs = a;
+    this.cliArgs.push(...a);
+    // Screenshots is `on` by default in CLI, so we
+    // disable it for all tests, unless enabled explicity
+    if (!(a.includes('--rich-events') || a.includes('--screenshots'))) {
+      this.cliArgs.push('--screenshots', 'off');
+    }
     return this;
   }